ABC150

5完。普通に問題の不備でunrated。かなしい。CDFあたり面白かったのでそれはよかったけど。最初問題が表示されなかったのは金曜開催によるものというのがまた(面白いと言ってはあれだが)。

A - 500 Yen Coins

自分の場合は、2分くらいで問題を見ることができて、最初の提出は失敗した。

k * 500 >= x。いい感じの難易度。

B - Count ABC

これも好き。全探索ではあるけど探索範囲でちょっと悩ませてくれる(自分は0で埋めた長い配列用意してN回調べた)。

C - Count Order

O(N!*N)が通るのでそのまま書く。B問題で使ったのでまたmemcmpしたが、比較しやすいよう入力をcharで受け取ったのが原因ではまった。入力を数値として受け取ってほしいのに文字で受け取ってる(charなのでそれはそう)。このミスは経験がある(繰り返すのほんとかなしいね)。next_permutationでN!回のループを回し、何回目で一致したかを返す関数を作って引き算する。

D - Semi Common Multiple

「公倍数を理解していますか?」と言われているようで困ったなあと思いながら色々試す。a_iの半分の1倍, 3倍, 5倍...が使える。奇数と偶数の「半公倍数」を考えてみると、奇数のほうを偶数倍しないとダメなことがわかる。もう少し考えると、因数として持ってる2の個数が違ったらダメそうだと気づく。そうでないとき、a_i/2たちの公倍数が最小の「半公倍数」。公倍数を求めていって、オーバーフローしないようにMを超えたら0を出力して終了する。(最小公倍数をrとして)最後、単にm / rを出力してサンプルが合わなかったが、奇数倍だけなので(m + r) / (r * 2)だった(この演算は32bit整数の範囲でできる)。

E - Change a Little Bit

Sは全部0として最後に2^Nを掛ければよさそうだし、f(S, S)=0と定義してもよさそうだし。ひねりの部分は拍子抜けするくらい楽。さて、Dはだんだん減っていくので、貪欲に小さいC_iから使っていくのがいい。Cをソートして、2^(N-1)回現れる各C_iの寄与を足していけばいい。例えば自分より大きいものが3個あったら、自分も含めて残り4個の状態で操作するのでD=4となる。4番目に大きいC_iから見ると、Tがどんな列かによって自分より大きいのが0個だったり1個だったり2個だったり3個だったりする。これは二項分布で対称なので期待値は1.5個。0.5の倍数を扱うために2倍してn - 1 - i + 2(2倍するタイミングがずれてサンプル合わないなーやってた)。最後に2^(N+(N-1)-1)を掛けて終わり。

F - Xor Shift

kはN通り、xはkが決まれば決まる。つまり、O(N^2)でよければ簡単。高速化を考える。全体にxorをかけても変わらないものとは?入力例3を2進法で書いてみるとぼんやりと法則が見える。周期のようなものがある?周期を全探索できたりする?この辺、計算量をしっかり計算していかないと感覚が利かない。そもそも周期があるものだけでいいのかというのはあるが、aとbに同じ周期があることがわかったとして位置合わせをどう高速にやるかというところ。「意外と愚直が通るのか?」「いや無理やろ」ほんと計算量が難しい。約数の個数とかその逆数の和とか。