ABCコンテスト 過去問感想 → ■
ARCコンテスト 過去問(~057, A・B難易度)感想 → ■
ARCコンテスト 過去問(058~, C難易度) → 近日
全体感想
20番あたりまでは全体的には易しめ。難易度変動は大きめで、難しいのは難しい(トートロジー)。その後、特に30番あたりからは、私にとってはかなり手強い問題になってきたなと感じました。
ABCコンテスト等だと、ソート・累積和・dfs・bfs・二分探索・漸化式など、競技プログラミングや情報科学に特化した勉強をしていなくてもすぐに扱えそうな技術が多い印象がありました。
敢えて悪く言えば、
・易しい知識に基づく速解き競争が中心。逆に、高度な専門知識を持っていても報われにくい
・問題を解く楽しさはあっても、高度な手法を学ぶ場としてはそれほど適していない
という印象も持っています。
今回の難易度帯から一気に、データ構造などの知識が問われ始めたように感じます。私としてはそういう分野特化な思考法を吸収できる方が嬉しいので、この難易度帯はこれまでと比べるととても充実していました。
難問リスト
個人的に数時間単位でかかったものなど。考察が難しかったもの、実装が難しかったものなどごちゃまぜ。一応雑にリストアップしておきます。個人差もあるかと思います。
・ARC019 最後の森
・ARC030 有向グラフ
・ARC038 茶碗と豆
・ARC046 合コン大作戦
・ARC052 高橋くんと不思議な道
・ARC054 鯛焼き
・ARC055 ABCAC
個別感想
ネタバレ防止も兼ねて、折りたたんでみました。
分かってしまえば難しい問題ではないのだが、かなりの時間悩まされた。
司会者からの供給が遅いので、各参加者が律速段階になる心配はしなくてよい。
したがって、司会者が投げ始めさえすれば、そこからは各参加者に理論値時間で届くとしてよい。
このことに気付くと、ただの最短路問題になった。
dx = X[:,None] - X[None,:]
dy = Y[:,None] - Y[None,:]
graph = np.sqrt(dx * dx + dy * dy)
graph /= np.minimum(T[:,None], R[None,:])
$(i,j)$ 成分に$X[i] – X[j]$, $\min\{T[i],R[j]\}$ 等を持つarrayを作るにはこのようにします。X[:,np.newaxis] と書いても等価です(np.newaxis is None)。
これはかなり難しかった。Grundy数を順に更新していけばよいことはすぐに分かる。これをどのようなデータ構造で実現すればよいのかいいのか悩まされた。
例えば、seg木で、区間に対してどのようなGrundy数が存在するのかを持たせることが思いつく。各区間に対してsetを持たせても、大きさの合計は $O(N\log N)$ で済む。
でもこれだと結局、存在しない値の最小値を求めるところが上手くいかない。各区間にBITを持たせる。いやそれは大きすぎる、無茶だ。
そこで立場を入れ替えてGrundy数に対して何かを持つ形のデータの持ち方を考えていたら、区間をコンプリートするインデックスを持つseg木で要件を満たせることが分かった。
seg木やseg木上の二分探索はBIT以上に経験がなく実装も時間がかかる。独学の適当なseg木だと、最下段に奇数番号の1元集合を配置してBITライクな添え字付けをしていたのだが、
アリ本を見直すと最下段を連番で持っていて、確かにその方が実装に頭を使わない気がしてきた。seg木が計算用紙なしでも書けるようになった。