ABC328

6完。Gがわからん。

A - Not Too Hard

X点以下の問題は解けて他は解けない人がABCで何点取れるかという問題。設定がわかりやすいのでそのまま書いて1分切り。

B - 11/11

月日の日だけ見て、そこがゾロ目になるのは高々2個(100以下なので3桁のゾロ目はなくて2桁と1桁があり得る)。ということで、各月について調べる。例えば3月なら、3がD_i以下なら1個、33がD_i以下なら1個という感じで数える。月がゾロ目か調べるの忘れてたし、1桁でないゾロ目の月にそのまま使って間違ってたし、だいぶやばい問題だと思った。時間もかなり奪われた。

単に全部の日付を列挙して文字列化して1種類の文字かを見ればよかったのか。

今日の日付と関係ある問題なの気づかなかった。問題名、見たり見なかったりなんだよなあ。

C - Consecutive

一転して面白そうな問題。累積和するだけなんだけど、具体的にどうするかが難しくてそこが面白い。図を描いて考えると、N-1個ある境界に0か1が割り当てられてその累積和があればいいとわかる。長さNのvectorを用意して0番目は0として累積和を構築する。0-indexedで[L, R)の区間にある境界(1からN-1の番号が付いている)は、Lまでは関係なくてその次からR-1までなので、そのように出力。

D - Take ABC

読むとシンプルな問題。なんか愚直にやれそうにも思えるが、削除したぶん縮めるのが難しいのかな。とか思ってると、(括弧列でよくある)スタックを使う方法を思いついた。末尾3文字が"ABC"になったら削除するだけ。リスト使えばいけんのかな。

E - Modulo MST

どーすんのと思ったけど制約を思い出せば全探索。28C7が100万くらいなのでいける。サンプルに最大ケースらしきものもあって安心。自分のUnionFindはvector使ってるけど、定数倍高速化したいとき用のarray版も持っといたほうがいいかな。AHCでもまれに使う。vectorインスタンスを100万回以上作るとそこそこかかってくるのよね(100万回で済むとわかっていれば気にしなくていいとも言える)。

F - Good Set Query

問題文が難しいけど、なんかもやもやした整数列に制約をかけていく感じ。よく見るとポテンシャル付きUnionFindだ。どうやるんだっけと思いながら頑張って改造する。実装を楽にするため経路圧縮をしないように書き換えて、親との差をleaderに着くまで足していけばポテンシャルがわかる。丁寧に書いて、しょうもない(bをnと書いてたなどの怖い)バグをいくつか取り除くとサンプルが通り提出してAC。

ライブラリを「ポテンシャル」で検索したらあった。ちゃんと経路圧縮もするやつ(leaderを求めた時点で親との差がポテンシャルになってて便利)。いやこれ思い出せなかったの痛すぎる。でもどっちみち使い慣れてなかったから時間はかかった。しかも、変に書き換えてWA食らったし。帰りがけに親のポテンシャルがわかった状態で計算するのね。

G - Cut and Reorder

N-1回分割するならソートで簡単だけど、そうじゃないときはソートみたいな操作はできないのかな。とりあえずDFS愚直書いてみたけど、実装も大変だし、デバッグが済んでも当然10秒とかでは終わらないし、高速化も見えない。DPも考えたけど、AとBの2個あるので2乗になってしまう。終了後、解説とか見たけど、Bを左から順に見るのはなるほどと思ったけどそこから先があまり理解できないし、自分で考えるとやはり2乗になってしまう気がしている。困ったね。

(追記)Bを固定してるんだから2乗にはならないよなあ。そのくらいわかってなかった。考察ができないとかじゃなくて、問題設定がわかってない。自分の語彙にない状況だったから。それがわかったら普通にDP書けばいいのだが、区間毎に遷移というのがわからなくて、だって順番に処理しないといけない(例えばbitDPで小さい順にやれば必要な情報が揃った状態で計算できる)のにそれができそうにないから。結局、それは計算量の見積もりに使うだけだったのか?書いてみれば単純で、2^N回にループの内側で対応する区間を全列挙。必要な区間数のオーダーでしか計算が発生しないので間に合う(あ、2^N*N回のループはある)。ていうかサンプルに最大ケースがあるからそこで確認すればよい。貰うDPにしたので、区間列挙は後ろから。実装はすぐ終わったが、悩んで無限に時間を浪費した。コンテスト中の集中力がないとマジで10倍の時間がかかる。