エイシング プログラミング コンテスト 2020の感想
(タイトル間違ってたのを修正。ABCではない。)
NoSub。Cから解くと決めていて、Cが解けなかった。
A
atcoder.jp
以上以下の範囲にある整数のうち、の倍数であるようなものの個数はで求められる。累積和的な考えを使うと、答えはである。
また、普通にループを使って以上以下の整数をで割って行ってもOK。だが、制約がなので余裕をもって間に合う。
B
atcoder.jp
ループを使ってすべての要素を見ていく。「前から奇数番目」と「が奇数」を同時に満たす場合だけカウントする。奇数か否かは、で割った余りで判定できる。一番最初の要素は番目ではなく番目である点に注意。
C
atcoder.jp
問題文を見たとき、まず等式
を思いつくが、良い変形が思いつかず断念。
とりあえず愚直に解くことを考えると、各に対して、変数の値を決め打ちして実際に等式が成り立つならカウントを増やす、という解が思いつく。の上限は指定されていないが、これらは全て正の整数なので、この変数のうちどれか一つでもを超えると明らかに式が成り立たなくなる。よってであることがわかる。愚直解の計算量はで、制約からだいたい回の計算が必要となる。
ここで、を決めるとの値は一つに定まる(∵未確定の変数が1つしかない)ことを利用すると、式変形して
となり、この2次方程式の解を求めればよいことになる。
(追記:ここの式変形が間違っていた!!正しくは、
です。)
は以上の整数であることに気を付けて実装すると答えが求まる。計算量が、制約から回と(ギリギリではあるが)時間内に終わるよう改善された…
と思って実装したのだが、なぜか答えが合わなかった。
(追記:この解法でも一応882msで通りました。)
Submission #15187699 - AIsing Programming Contest 2020
フォロワーさんから聞いた解法を一応残しておく。一度を考えず単純にを全探索して左辺の値を求め、その値がからの範囲内なら配列でカウントしていき、最後に配列の値を順番に出力すると計算量が、回で求まる。確かにこちらの方が計算量も少ないし、スッキリとした解法である…。
D
atcoder.jp
まず愚直解を考える。ある数に対して、 → は必ず減少する。さらに言うと、2進数で表現したときの桁数はだから、は最大でもである。余りをとる計算の性質からで割った余りは以下になるので、一度の操作で大きさが倍になる。
つまり、二進数で表現したときの桁数がであるような数に対して、を求めるには回桁を見れば良いことになる。まあ大体で求まると考えて問題ない。
全てのに対してこれをやると計算量はとなり間に合わないので、高速化を考える。
よく見ると、もとの数とを比べると高々bitしか違わない。ということは、ともしか違わない。具体的には、の値はか、かの2択である。どちらの値になるかは、桁目がかかを見れば決まる。
また、をそのまま10進数に直そうとするとというとてつもなく大きい数字になってしまうが、最後に余りをとることがわかっているなら、最初から余りをとった値を扱えばよい。具体的には、「をで割った余り」と「をで割った余り」のデータがあれば、「をで割った余り」をで求められる。あとは数字がそこまで大きくないので、素直に操作を繰り返すことでの値をで求められる。
これをの個数分(回)繰り返すので、全体の計算量はとなる。がになる場合、余りの計算が出来ないので例外処理を書く必要がある。
E
atcoder.jp
見ていない。ぱっと見、データ構造を駆使しそうなイメージ。
F
atcoder.jp
C問題の強化版みたいな見た目をしている。全体で見てもかなり難しいらしい。
感想
NoSubはなるべくしないように心掛けているけど、Cが解けないのはまずいと思って考えているうちに提出しないまま終わってしまった。反省。