AtCoder Beginner Contest 174 感想
あばばば
— scol (@scol_kp) 2020年8月2日
scolさんのAtCoder Beginner Contest 174での成績:2243位
パフォーマンス:1149相当
レーティング:1528→1495 (-33) :(#AtCoder #ABC174 https://t.co/cEFUstCbJ8
ABCEの4完。
Cで時間をかけてしまい、そこから調子が狂って破滅しました......。
晩御飯をコンテスト直前に食べるのは良くなかった(負け惜しみ)。
A - Air Conditioner
リンク: https://atcoder.jp/contests/abc174/submissions/15589788提出コード
void solve() {
ll N;
cin >> N;
bool ok = N >= 30;
cout << (ok ? "Yes\n" : "No\n");
}
B - Distance
念のため、 で判定した。
リンク:https://atcoder.jp/contests/abc174/submissions/15598123提出コード
void solve() {
ll N;
cin >> N;
double D;
cin >> D;
ll cnt = 0;
for (ll i = 0; i < N; i++) {
double x, y;
cin >> x >> y;
double d = sqrt(x * x + y * y);
if (d <= D + 1e-9) {
++cnt;
}
}
prints()(cnt);
}
C - Repsept
めっちゃ時間かかった......。
番目の数を とすると (0-indexed)
だから、 には周期性がある。なので、 から順番に調べていき、もし、 となる前に 前に登場した値になったら -1 を出力する。周期は長くても なので計算量は大丈夫。
はじめに、この前のこどふぉの問題に引っ張られて式変形を試みて時間をかなり消費したのがダメだった。
リンク:https://atcoder.jp/contests/abc174/submissions/15618564提出コード
void solve() {
ll K;
cin >> K;
bool ok = true;
ll cur = 7 % K;
ll base = 1;
ll ans = 1;
set<ll> st;
while (true) {
if (cur == 0) {
break;
}
if (st.find(cur) != st.end()) {
ok = false;
break;
}
st.emplace(cur);
base *= 10;
base %= K;
cur = (cur + 7 * base) % K;
++ans;
}
if (ok) {
prints()(ans);
}
else {
prints()(-1);
}
}
D - Alter Altar
解けなかった。
「この問題、超むずかしいですよねぇ!?ねぇ!!?」と聞きまくって共感を得まくりたいところだけど、 順位表を見るとどうやらそう思っているのは僕だけらしい。え、マジ??
ちなみに、まだ解けていません。解説PDFは死んでも見たくない......。
[追記]
解けました。セーフ!(アウト)
WW...WRR...R となっている塊(ダメ塊と呼ぶ)がなくなるように操作すればいい。 ここでよく考えると、入れ替える操作はダメ塊の構成要素を少なくとも1つ以上消せるのに対し、色を変える操作は1つしか消すことができない。 また、色を変える操作によって消せる要素は入れ替える操作でも消せる。なので、色を変える操作は必要ない!
入れ替える操作だけでいいなら最終形態は確定して、RR..RWW..W のようになればいい。 最小の操作回数でこの形態にするためには、 の両端から見て行ってこの形態に違反している要素同士を swap すればいい。
リンク:https://atcoder.jp/contests/abc174/submissions/15646447コンテスト後提出コード
void solve() {
ll N;
cin >> N;
string S;
cin >> S;
ll cnt = 0;
ll left = 0, right = N - 1;
while (left < right) {
while (left < N && S[left] != 'W') ++left;
while (right >= 0 && S[right] != 'R') --right;
if (left < right) {
++cnt;
++left;
--right;
}
}
prints()(cnt);
}
E - Logs
Dがさっぱりだったので、終了20分前にDを飛ばしてEを解き始めた。このムーブのおかげで何とか緑パフォを出す損害に抑えられた。
はじめに、焦りすぎて の制約を見ずに priority_queue を使って大きいものから分割数を増やしていく解答を投げて1回 TLE を食らったものの、 その後すぐに二分探索が見えたので助かった。
Dの方が998244353倍むずかしいです。
リンク:https://atcoder.jp/contests/abc174/submissions/15638921提出コード
void solve() {
ll N, K;
cin >> N >> K;
Vl A(N);
for (ll i = 0; i < N; i++) {
cin >> A[i];
}
ll left = 0, right = 1001001001ll;
while (right - left > 1) {
ll mid = (left + right) >> 1;
ll cnt = 0;
for (ll i = 0; i < N; i++) {
ll x = (A[i] + mid - 1) / mid;
cnt += x - 1;
}
if (cnt <= K) {
right = mid;
}
else {
left = mid;
}
}
prints()(right);
}
F - Range Set Query
読めてない。しかし、僕がかつてライバルだと思っていた人たちはみんなこれを解いている。すげぇ。
今では彼らは雲の上の存在です。
[追記]
考えても分からなかったので「区間 種類数」と検索したら答えが出てきた。草。
Twitter が騒がしかったのはこれか、笑。これは検索力もくそもないので、お気持ち表明する人が出てくるのもまぁ仕方ない。
検索して出てきたアルゴリズムを書くとACを得た。色の所有権を管理していく感じだね。
「クエリは別に順番通りに処理しなくてもいいよ!」というのは持っておくべき考え。
リンク:https://atcoder.jp/contests/abc174/submissions/15648146コンテスト後提出コード
template <typename T>
class BIT {
private:
int n;
std::vector<T> vec;
public:
BIT(int n) : n(n), vec(n + 1) {}
// i 番目の要素に a を足す
void add(int i, const T& a) {
for (++i; i <= n; i += i & (-i)) {
vec[i] += a;
}
}
// 区間[0, i)に対するクエリを実行する
T query(int i) const {
T res = 0;
for (; i >= 1; i -= i & (-i)) {
res += vec[i];
}
return res;
}
// 区間[i, j)に対するクエリを実行する
T query(int i, int j) const {
return query(j) - query(i);
}
size_t size() const noexcept {
return n;
}
void reset() noexcept {
std::fill(vec.begin(), vec.end(), static_cast<T>(0));
}
};
void solve() {
ll N, Q;
cin >> N >> Q;
Vl C(N);
for (ll i = 0; i < N; i++) {
cin >> C[i];
--C[i];
}
using Tup = tuple<ll, ll, ll>;
vector<Tup> queries(Q);
for (ll i = 0; i < Q; i++) {
ll a, b;
cin >> a >> b;
--a;
queries[i] = {b, a, i}; // 左右逆
}
sort(queries.begin(), queries.end());
BIT<ll> bb(N);
Vl la(N, -1);
ll cur = 0;
Vl ans(Q);
for (ll i = 0; i < Q; i++) {
auto [right, left, idx] = queries[i];
while (cur < right) {
if (la[C[cur]] != -1) {
bb.add(la[C[cur]], -1);
}
la[C[cur]] = cur;
bb.add(cur, 1);
++cur;
}
ans[idx] = bb.query(left, right);
}
for (ll i = 0; i < Q; i++) {
prints()(ans[i]);
}
}