ABC179

今日のABCのwriter見て楽しみと思ってたら、明日のwriter見てさらに緊張してくる。楽しみなのはいいけどそのぶん緊張みたいなのがあるよねw

A - Plural Form

Aで1000文字は珍しい。簡単ではあるけどAにしては実装が重く1分以上かかった。

B - Go to Jail

最大で何回連続したか数えればいい。現在の連勝(勝?)数を更新していけばよい(ゾロなら1足してそうでなければ0にする)。最初、現在の連勝数を出力していてサンプルが合わなかった。その最大値も更新していって最大値を出力する。

C - A x B + C

かなり難しそうな見た目。実際けっこう厄介。まず A*B=N-C と変形すると、1以上N-1以下の数それぞれについてA*Bが何通りあるかわかればいい。しかしこれは約数列挙になり時間がかかる(今考えるとO(N√N)だから行けるな(いや10^6かどうだろ))。調和級数で行けそうな雰囲気は感じていたので、その方向で考えて、Aを固定して積がN-1以下になるBを全探索でO(N*log(N))。最初、1以上N-1以下の数それぞれについてやろうとしていたため、引っ張られて冗長なコードになった。

(改めて書き直して)答えintに収まるんだなと思ってよく見ると割り算すればlog付かない。さっき解説見たけどそう書いてあったの読めてなかった。

D - Leaping Tak

問題の趣旨がわかるまでに5分くらいかかった。「つまり(この問題における)区間は集合なのか?」と思っていたら直後に集合だと書いてあったし、といって先に全体にざっくり目を通そうとしても何もわからんし、問題文を読むスピードがない。

集合Sのサイズが10とかならDPでできる。区間なのでどうするか。しばらく全然わからなかったが、普通のDPを思い浮かべれば同じことができそうだ。左から見ていき、そのマスから見て各移動元の通り数を全部足すだけ。これはBITでできる。998244353で割ったあまりをBITに入れるのでちょっと心配だったが、各マスに998244353で割ったあまりの通り数を入れるだけなので問題ない。

(解説を見て)うわ配るDP思いつかなかった。普通にいもす法やん。貰うときもlog落とせるのか?(コンテスト中はこういうの考える時間がないからね、コンテスト後のお楽しみ)
(貰うDPのまま考えて)普通に累積和でできたわ。コンテスト中に落ち着いてここまで見据えたいところ。上で「ちょっと心配だったが」と書いたところ、それが問題ないとわかった時点で気づいてほしい。

E - Sequence Sum

この見た目。X, X^2, X^4, X^8...とか考えてわからんのでFをちょっと読んだりしてた。さて、よく見るとこれはあれだ。A_iとしてありえる数が高々M通りで直前の要素にしか影響受けないから長さM以下の周期がある。途中からループに入るやつ。またこれかよいいかげん飽きた。実装かなり面倒なのでこうも頻繁に出されるようだと対策考えないとな。いやAtCoderで要る?

Nが1000000未満なら愚直。そうでないとき必ずループに入るので、ループまでとループのぶん*ループ回数とあまりを足した。

F - Simplified Reversi

各方向、置いた最も小さい座標を更新していくだけでは?と思ったけどなるほどそういうゲームか。しかしこれは遅延セグ木でも使えばできるのでは。ただまあ区間更新1点取得なのでまたBITが使える。N-1とかN-2とか区間更新どうやるんだっけとかめがっさ混乱した。更新する区間の長さの取得に突き当たった位置が必要でそういうの全部正確にやらなきゃいけなくて。そうこうしているうちに、陰になってる場所のときは更新しなくていいことを忘れる。BITだからaddしかなくてyをxに変更したいときx-yを足す必要があるんだよね。このへんもっと簡単にできるのかとかなんにもわかってない。

Twitterを見て)なんかO(N)でできるらしい。俺もそんな気はしていたがコンテスト中は(ry

解説を軽く見て意味はわからなかったが、その後自分で考えていたときに解説の「関係しないことがわかります」という部分の意味がわかってしまった。配列の外側から埋まっていくのかあ。その向きは想像できてなかった。