2022-01-20 第八回 アルゴリズム実技検定 (PAST) I - /2 and *3 を解いた
第八回 アルゴリズム実技検定 (PAST) I - /2 and *3 を解いた。
問題: https://atcoder.jp/contests/past202109-open/tasks/past202109_i
2 で割って 3 を掛ける操作を繰り返す。少なくとも対象を同一にすれば単純に 3/2 倍で損はない。つまり操作は最大回数まで繰り返すのが良い。
操作の最大回数 C は各項の 2 で割れる回数の総和になる。はじめにすべての項を 2 で割れるだけ割ってその回数の総和と割った後の数列 B を得る。この処理における最悪ケースが 10^5 個の 10^9 のときだ。各要素はたかだか 30 回程度のはずなので C <= 3 * 10^6
になる。
あとは数列 B の最小値に対して 3 倍する操作を C 回繰り返す。
操作後の新たな最小値を求めるために数列 B 全体を走査すると O(CN)
となって間に合わない。そこで優先度付きキュー (Rust なら BinaryHeap) を使う。最小値をデキューして 3 倍してエンキューする。これで O(ClogN)
になるので間に合う。
操作を C 回繰り返して 64 bit 型の数値におさまるのかについてはおそらく大丈夫で、操作対象は数列全体におおむね均等になるはずで、さきほどの最悪ケースで考えても各要素 30 回程度になるはず。 3^32 でも 2^64 よりは小さい。不安なら u128 で殴ればなんとかなるはず。
解説: https://atcoder.jp/contests/past202109-open/editorial/2726 提出: https://atcoder.jp/contests/past202109-open/submissions/28641509
今日のコミット。
- rust-atcoder 1 commit
- rust-sandbox 2 commits