ICPC2023 国内予選 参加記

チーム suzukaze_Aobayama (milkcoffee, karinohito, sotanishy) で,ICPC2023 国内予選 に参加した.

このチームは,今のメンバーでは2年目である.そして,milk さんの参加資格が今年で最後なので,このメンバーでやれるのは今年が最後になる.

コーチはこたつがめさんに担当していただきました.ありがとうございます.

目標は国内5位 & 学内1位.

本番前

今年の国内予選はコロナ以前のルールに戻った.PC1台ライブラリ写経ルールは去年のアジアのときに練習してある程度慣れていたので,そこまで心配はしていなかった.

本番1ヶ月前から毎週チーム練を行った.流石にICPC4年目だと,国内の過去問は一通り走ってしまっているので,Codeforcesのgymにある海外regionalを適当に選んでバチャをやった.

6/24の模擬国内では 6完,ゲスト除いて3位 (!) という好成績を収めた.遅い愚直を回している間に他の問題の実装をするといったような,国内予選特有の立ち回りがうまくできた.3位なんてまぐれでも取れると思っていなかったので,やばい!

本番1週間前に,模擬国内2018のバチャをやった.本番2位相当 (!) の結果だった.このチーム,強いぞ.

本番2日前に,模擬国内2020のバチャをやった.信じられない冷え方をした (通過できないレベル).ちょっと不穏な空気が漂う.

本番前日.いくつかAOJ-ICPCを解いたり,ライブラリを追加したりした.早めに就寝.ICPCが気になりすぎてあまり寝付けなかった.

当日

10時頃起きる.研究室に行って院試の研究計画書を書いていた.あとは研の同期に順位表のスクショ撮影をお願いしておいた.

14時頃,参加場所である別の研究室に移動してチームメイトやサークルメンバーと合流.場所を決めたり印刷についての取り決めをしたりした.あとはリハーサルの問題を解く.JKLが終わったのが終了10分前.Mの鎖中経路10分実装チャレンジが始まった.毎年これやってるから,もう問題文見なくてもコードがだいたい書けるくらいなんだけど,10分は,無理.幾何ライブラリの写経でほとんど終わり.

本番まで1時間半ほど微妙な時間がある.エナドリとお菓子の買い出しに行ったり,同じ部屋にいたチームや,見に来てくださったこたつがめさんとホスフィンさんと雑談したりしていた.

↓ これ見て爆笑してた.

適当にAOJの簡単な問題を解こうと思い,250点の Leaky Cryptography を開いた.問題文の読解にかなり時間がかかり,理解して実装したあともサンプルが全然合わず,チームメイトに助けて〜って言っていたらそもそも10進数から16進数への変換のところがバグっていることに気づいた.脳が死んでいる.なんとかAC.

開始10分前くらいになると流石に緊張が高まってくる.もうICPC4年目だけど,いつまで経っても緊張するんだね.

本番開始

A (AC 3:26)

僕がAをやる間に,問題文が届き次第チームメイトが前から適当に考察を始めるというのが初動.Aは問題文も短いしやることも簡単なのでいいね.かなりスムーズに実装できてすぐにAC. FA行けたんじゃね?と思っていたら 3rd ACだった.FAは同じ部屋にいたAobayama_doctors.FA取る!って宣言してまじで取っていてすげ〜.

ラボの同期くんが撮ってくれた

B (AC 18:51)

Aをやっている間に kari くんが考察できていたらしいので任せる.通る.

kari くんがBをやっている間,milk さんがC,僕が D を読む.何もわからん.

C (AC 32:12)

Bが終わった時点で,milkさんが一緒に考察したいと言っていたので,Dを kari くんに渡して僕はCに合流.

もういかにも天才構築って感じの設定で,こんなのがCに出るの怖すぎ〜と言っていた.方針が立たなくて唸っていたら,milkさんが「偶数行を n/2, 偶数列を n/2 ずらせばいける?」とつぶやく.これはいかにも正しそうで,すぐに頭の中で証明ができたので,パソコン席に座っていた僕が実装に飛びつく.念のため丁寧にassertを書く.O(n^2) でassertするのだるくね?思って制約を見に行ったら n <= 50 だったので甘えて O(n^4) でassertした.assertのほうが実装が面倒で,そっちを主にバグらせていた.assertのバグが直ったら,構築部分のバグが発覚し,assert書いてよかった〜と思った.テストケースも全部assert通ったのを確認して提出,AC.

これきれいだよなあ.これをすぐ思いついたmilkさんめちゃくちゃすごいんだよな.

Cがかなり速かったおかげで,この時点でかなり上位だったみたい.

毎年,Cまでは爆速なんだ.問題はここから.

D, E, F

Dをやっていたkariくんの方は,解の上界がかなり小さいので全探索できるという方針が立ったらしく,実装を任せる.その間,僕がE,milkさんがFを読む.

Eは,DPをデータ構造で高速化するような見た目をしているが,制約的に変だなと思っていたのでもっといい感じの方針を探る.てか各ケース n <= 6000 で,データセット全体でのnの総和が 1e5 ってなに?2乗で大丈夫なんですかね.logつけたらやばそう. (←国内だと余裕なんだよな〜なぜその発想が模擬国でできて本番でできない)

まず数字が1種類しかなかったら最長減少部分列を取ってくれば良いから,それをいい感じに2次元に拡張できないかな〜と考えていた.単にペアの最長減少部分列を求めると,午前午後両方変える場合が扱えなくて厳しい.午後をDPで固定して午前でLDSをやるとかも考えたけどあまりいい感じにならない.

その間にFのいい感じの考察がmilkさんから降ってきたので.そこから2人で考察を発展させる.「凹んでいるところの両側の辺が一直線上にあり,かつ図形の反対側に平行な辺がある」が条件になると考えて,正しそうということになった.しかし,良い感じの実装方針がぱっと思いつかず,かなり沼る予感がしたので,DEを解いて時間が余ったら戻ってくることにした.

(この考察,嘘だったな.反対側に平行な辺がある必要はない.)

Dが結構バグっているらしく kari くんが格闘している.やばそうなので見に行き,ラバーダックになっていると,どうも話が噛み合わない.すると kari くんの誤読が発覚した.使う数字の総和が n にならなければいけないという条件を見落としていたらしい.これ見落とすのは仕方ない感じがあるな.......でも直せるらしいので再び任せてEの考察に戻る.

Eは2次元DPの方針が立つ.午前,午後の値をキーに持ち,最後の値をキーに一致させるのに必要な最小の操作回数を持たせる.3乗に見えるが,午前午後両方変える場合は午前をできるだけ大きくして損しないので,結局更新すべき状態は O(n) 個しかないことがわかる.これで全体で O(n^2) になる.でもこれ実装したくねえな〜場合分け書きたくねえな〜と思う.

その間,Dのサンプルがあったらしいので投げる.落ちる.かなりやばい雰囲気が漂う.Eを離れてDの鎮火に向かう.

D (AC 2:06:17+3ペナ)

再びラバーダックになる.途中まで説明を受けた段階でかなりやばそうなところが見つかる.コードを口で他人に説明するの,まじで大事.直したら diff が出たので投げるとまた落ちる.

全体の説明を受けてから提出すればよかった.焦りが出ている.コードの続きを説明してもらう.すると怪しそうな枝刈りが見つかる.それを消して再び実行.かなり遅いが,各ケース10秒も待てば出力が得られることを確認し,最後まで走らせる.するとdiffが出ますね〜.コード全体がいい感じになっていることを再確認し,提出.Correctが出たときは本当にホッとした.2ケース目も通り,Congratulations!

Dの全探索がすぐに見えたkariくんかなり天才なんだよね.僕は何も分からなかったので.ただ丸投げしたのが良くなかった.チーム戦をするべきだった.


E (解けず.2WA)

残り1時間.流石にEをやるかな.例の2乗DPを実装する.丁寧に場合分けしながら実装.O(n^2) のDPテーブルを持って,O(n) 個の状態だけ更新する.遷移元も O(n) 個しかないので計算量はいい感じだが,僕の取った方針だとかなり場合分けが大変になっちゃう.実装してしばらくデバッグすると,サンプルが合う!テストケースを実行.2乗だと結構遅いんじゃないかと思ったけどほぼ一瞬だった.投げると落ちる.これが終了15分前くらいだっけ?みんなでデバッグするためにコードを印刷しようとしたが,印刷されない.リハーサルのときも印刷されたりされなかったりでよくわかんなかったんだよな.仕方なくパソコンの画面を全員で覗き込む.コードを見返すと,考慮し忘れていた遷移を見つけたので実装.もう残り2分くらいなので,急いで提出.また落ちる.もう一度コードを眺めていると,見落としている遷移がもう一つあることに気づく.さっき直したところと同じようなところだったので,最初からこれも気づくべきだった.でももう残り10秒とか.無理だね.......

終わり.


本番後

恐る恐る順位表を開く.29位.Tohoku の文字列を検索する.suzukazeの上に2個あるね......でもギリギリ3チーム通過圏内だったりしない?僕らより上の東大をみると,どこも落ちてないじゃないか!東工大が2つ落ちている (1つはホスト枠で通るけど) ので,それを除くと27番目か.3チーム通過のためには25番に入る必要があるんだよね.

え?

かなり信じられなくて,現実感がないふわふわした時間がしばらくあった.

どうしようもないので別チームと一緒に感想戦をする.1年生チームのrnnの,Eに対する考察を聞いて大声が出た.操作回数をキーに持って,達成できる最大のペアを持てばいいんだね.これも結局 O(n^2) で計算量は変わらないんだけど,見通しの良さが格段に違う.かなり衝撃的だった.

Aobayama_doctorsはDをかなり速く通していてすごい.その後Fをやっていたらしい.かなり正しい考察をしていたっぽいが落ちたらしい.あれを実装しきれるのすごいな.

東北大通過2チーム目の Aobayama_primes は,正直完全にノーマークだった.最近黄色になった suo くんのチーム.Dが速くて,強い.

その後軽く打ち上げに行った.帰宅に失敗.逆方向の終電に乗っていた.......結局ネカフェに転がり込んで夜を明かし,始発で帰った.

振り返り

チーム戦をしなかったのが良くなかったんじゃあないかなあ.Dとか考察をまともに聞くことすらせず何もかも丸投げしてしまった.バグって苦しいのを1人で長い間戦わせてしまったのは本当に申し訳ない.

あとE,1時間あれば通さなきゃいけないだろう.はずれ方針とはいえ,1時間あれば実装しきれるはずのものだった.

未練しかない.どうすればいい?

本番終了後は現実を受け入れられずヘラヘラしていたけど,一晩経ってこれ書いてたらもう終わったことが理解された.

とにかく,国内通過した Aobayama_doctors, Aobayama_primes,おめでとう.アジア頑張ってください.全力で応援します.

チームメイト,お疲れ様でした.ICPCはこんな形で終わってしまったけど,2年間一緒にICPCできて本当に楽しかった.チームとしてはこれで終わりじゃなくて,また有志コンとか出たいね.

今まで4年間のICPCを通じてありとあらゆる感情を経験した.今年は未練しかない.