TUPC2023 感想

東北大学プログラミングコンテスト TUPC2023 を 2024/03/09 に開催した.公開が遅くなってしまったが,準備の裏話や,問題と当日の感想を書く.

準備について

夏頃に運営の募集をかけた.今年はwriterとして,去年からの僕,仮の人君,とりゐ君,milkcoffeeさんに加え,Dispersionさんとnonon君の計6人が集まった.Dispersionさんは一昨年のTUPC2021ではwriterをしていたので,新顔は1年生のnonon君.人数が増えた分,問題が集まりやすくなってよかった.
それから半年以上時間をかけて準備を進めた.運営陣のほとんどが学部4年生以上で,それぞれ本業が忙しかったりするので,これくらい余裕を持って進めるほうが楽である.また,時間をかけて問題を熟成させたほうがクオリティが上がることは間違いない.

準備は非常にスムーズに進んだ.TUPC2021から蓄積してきた作問ノウハウに加え,去年のオンサイト運営の経験もあったので,特に何も困らなかった.

去年の反省点を鑑みて,いくつかの変更や改善を試みた.去年の一番の失敗は難易度予想を外しまくったことだったので,今年はちゃんと各testerが初見のときの気持ちを重視して難易度評価をするようにした(本当?少なくとも僕はそうしたつもり).また,コンテスト時間は5時間にした.さらに,難しすぎて緑〜黄くらいの人が終盤暇になってしまう(去年そうだったのかは知らない)という点に対処するために,いくつか部分点をつけてみた.

超強い全体testerの方々だけでなく,一般人(失礼)の感想も調べるために,サークルからsuo君,ripity君,tanaka2_55君を呼び寄せて走ってもらった.手頃な部分点がいろいろあるおかげで,暇にはならなさそう,という感じだったので安心したが,本番では果たしてどうなるか......?

ところで,AtCoder上のTUPC2023のトップページにはTTPC,OUPCをまねて虹色marqueeを配置した.クリックするとなんらかのエフェクトが起こるのが恒例なので,我々はクリックする毎にサイズがランダムに変動するように仕掛けた.大きく育ててツイートをしている人を見ると,作りがいを感じる.

問題について

今年は共同作問や魔改造が多かったと思う.今までのTUPCでは,解法まで出来上がっている状態でテスターに共有することがほとんどだったが,今年は解けてない原案も積極的に共有されていた.

僕がwriterを務めたE, G, H問題の話が主になるが,他の問題もtesterやsolverとしての感想を書きたいので書いちゃう.

A - Namboku / Tozai Line

東西線の西端である八木山動物公園駅は,「日本一標高が高い地下鉄駅」として有名である.

B - 012 Grid

testerをした.超難しく,自力で解いていない.経路問題になってLGVを使いそうということはなんとなく分かるが,そこから先の議論が鮮やかで,めちゃくちゃおもしろい.
B問題から難しくて申し訳ないが,ランダムシャッフルしたらこうなったので仕方がないのです.

C - Topological Sort

testerをした.設定も解法もシンプルで面白い.僕はかなり難しいと思った.ARC-BとかCに置かれていたらかなり詰まりそうな感じ.

D - Shift Puzzle

数時間かけて自力で解いた.3点の回転で2点swapができるのめちゃくちゃ面白くないですか.実装はちょっと大変.

E - And DNA

writerをした.下の桁から考えていくのは典型的で,それが結構うまくはまる.

問題文が回文の問題を作りたいと思い,問題名が生えた.DNAみたいなはしごを描いて,数字とか&とかを適当に配置することで設定を生んだ.

ところで,この問題みたいに行列累乗してトレースを取るという操作は,統計力学の「転送行列法」っぽさがある.卒研が統計力学なので統計力学を結構勉強したが,いろいろ競プロに応用できそうなテクニックが眠っていそうな雰囲気を感じている.

F - Hotel

このセットでは唯一ABC-likeな問題だと思う(writerもそれを意識して作ったらしい).題材が面白い.

G - Min Nim

writerをした.回文シリーズ2.これも問題名から設定を生やした.実験をしたところ,Nが奇数なら先手が必ず勝てることがわかった.理由を考えると,偶数のときの解法もわかる.

これは人によって難易度評価がかなり違った.速い人は2分で解いたけど,詰まってしばらく解けなかった人もいた.僕自身は緑くらいだと予想していて,結果的には的中した.

H - Count Pseudo-Palindromes

writerをした.回文シリーズ3.これは回文というテーマから設定を生やした.K問題の101点を除いて,予想難易度が一番高いボス問である.本番も1ACだった.

僕は問題設定と計算量の悪い解法だけ生んでtesterに投げたら,気づいたら線形時間になっていた.この問題は,チーム作問がかなりうまくいった例だと思う.

準備はひじょ〜〜〜に大変だった.作問の背景を話す.

去年の春に,擬回文の存在判定の問題を考えた(1からXが1つ,X+1からX+Yが2つずつ現れる,というふうにすると非自明になる).僕はそれをdominator treeに帰着させることでO(N (log N)^2)で解いた.判定問題だと嘘解法がいろいろありそうなので,数え上げにしたいなあと思っていたが,よくわからずしばらく放置していた.秋頃に考え直したところ,すごく頑張ると解けることがわかった.dominator treeはやっぱり使う.実装がライブラリを除いて200行を優に超えるような大変な解法である.まあ有志コンのボス問としては許されるだろうと思って準備を進めた.
しばらくこれが唯一の解法だったが,年が明けてから新しい解法がいろいろ提案された.とりゐ君が天才考察によりO(N)の解法を見つけてそれが想定解となったほか,仮の人君,Dispersionさん,こたつがめさんが O(N√N) や O(N log N) で解いた.人によって解法がかなり違っていて面白い.
O(N)で解けることがかなりすごいので,制約を大きくすることで O(N)を強制しようとしたが,O(N log N)はともかくO(N√N)も爆速で落とせそうになかった.O(N)解法はハッシュマップを使うので定数倍があまり良くないというのもある.それでも,O(N)解法に少しでも考察量を近づけるために,擬回文の中心ごとに個数を数え上げさせることにした.これで難易度がだいぶ上がったと思う.
それでもちゃんと全体testerのhenoさんには解かれて,やっぱりすごいなあと思った.

本番では,4時間経過しても0ACだったので,ACが出ることをほとんど諦めていたが,唐突にhamamuさんがACを取ってびっくり仰天した.それも,計算量の悪い解法をひたすら高速化する感じではなく,多分想定解に近い考察がなされていた(?)ので,すごい.なんなら想定解の実装より短くて高速.0ACだと悲しいので,ACが出てとても嬉しかった.

I - Maximize Array

セットの中では簡単枠だけど,ちゃんと考察が要求されていてそこそこ難しいし面白い.

J - Colored Complete Graph

testerをした.インタラクティブとしてめっっっっっちゃ面白い問題だと思っている.まず2N回でできるというのが驚き.僕はしゃくとり法みたいな方針で考えて,整理すると想定解と一致した.あとで「赤の連結成分数+青の連結成分数を減らす問題と捉えると筋が良い」と聞いて納得したが,このレベルの理解を短時間でできたらすごいと思う.

僕は橙くらいあると思ったんだけど,かなり解かれて水くらいになった.

K - (mod HW+1)

100点 (mod N^2+1) の方は2時間くらいで自力で解いた.合成数のときはほとんどできないが,1個だけ例外があるというのが面白い.素数のときの構築も楽しい.101点は,解いていません.100点の方は普通に解かれると思ったが,結局誰にも解かれなかった.

L - Random Mex

nonon君が原案.提案時の想定はO(NM)のDPだったが,tester陣により魔改造された.FPSで殴ると,Stirling数を含むかなりきれいな式が得られる.組合せ論的な解釈を考えると,公式解説にあるような議論が出てくる.ただこれをいきなり思いつけるかと言われると無理なので,実質的には式変形を頑張る感じの問題だろう.

M - Vivid Colors

testerをした.2次元の問題に落とし込むというところまではすんなりわかったが,実装があまりにも難しい.誤差が怖かったのですべて整数で扱おうとしたら,複数の点が同一直線状に乗るときに壊れまくるらしくて永遠に答えが合わなかった.浮動小数点数で雑に処理したら逆にうまく行った.ユーザ解説参照.

テストケースづくりが大変だったみたい.他のtesterがたくさん嘘解法を提案してくれて,それらを落とすのが難しかった.焼きなましでテストケースを作ったらかなり強くできたみたいで,すごい.

N - Do Not Turn Back

testerをした.サークルで雑談をしているときに,「この問題ってどれくらい速く解けますか?」とnonon君に出題されたので,その場に一緒にいた仮の人君と考えた.制約無しで問題を考えるのって結構難しいんだよな.戻らないという条件がない場合はO(N^3 log K)より速くなることはないと思っていた(実は速くなるらしい!後述)ので,これにどれくらい近づけられるかが問題.結局,同じO(N^3 log K)まで計算量が落ちてびっくりした.行列の3項間漸化式ってはじめて見た.すごく面白かったのでTUPC行き.BMBMを使うと2乗になるらしい.

O - 0100 Insertion

testerをした.解けていない状態で原案が共有された(もとは0010で,判定問題).サンプルをいくつか作って数時間睨むとすごい条件がエスパーできて,証明もうまくはまる.
考察を積み重ねて解く感じではなく,見えるか見えないかみたいな問題でしか得られない栄養素がある.個人的にはこのセットで一番好きな問題.

0100に反転することで難易度が大きく上がると思っていたが,これをコンテスト中に唯一解いたHemimorさんは結構違う方針を取ったらしくて,0010でも0100でも難しさが変わらないらしい.20分くらいでわかったと聞いて驚愕した.

P - Sub Brackets

testerをした.一番contestantの反応が良かったように見える.面白いですよねえ,これ.最大独立集合になるところまでわかって,そこからどうすると考えたときに,グラフが二部グラフになっていると気づいたときは感動した.どこにも二部グラフ的な構造は明示されていないのに,都合よく二部グラフになってくれているのがあまりにもきれい.

当日,オンサイト会場について

内職をするつもりだったが,順位表が気になりすぎて5時間張り付いていた,って去年も同じこと言っていたな.......張り付いていました.

序盤の解かれ具合が想像よりだいぶ遅くて焦った.難易度シャッフルがあるせいだろうか.
時間が経つと,想定に近いAC数順に落ち着いてきて安心.
4時間経っても,H, K, MにACが出ていなくてちょっと不穏になってきた.毎年,「すべての問題にACが出るが全完は出ない」を理想としてきて,実際に達成してきたが,今年は0ACが3問も出てしまうのかと心配した.ただそこからH, Mが解かれた(本当にすごい).一方Kについては,101点は端から期待していなかったが,100点すら出なかったのは驚き.まあ全体的には耐えたかな〜という感じ.

終了後,difficultyを算出して予想と比較した.解説スライド*1に載っているので見ていただきたいが,多くの問題でめちゃくちゃ正確に予想が的中していて驚いた.去年の反省が効いていて良い.大きく外したのはJ (過剰な見積もり) とD, K, M, O (過小な見積もり) くらいで,それ以外は±100くらいに収まっている.

終了後の懇親会で参加者の感想などを聞いた.問題がおおむね好評でうれしい.あとは,部分点をつけたおかげで暇にならなかったという声も聞いて,狙い通り.

最後に

僕は今月で東北大学を去るので,TUPC2023がpuzzleknotのメンバーとしての最後の活動であった.いろいろ言いたいことはあるが長くなるので,非常に感慨深いとだけ述べておく.

皆さんご参加ありがとうございました.
puzzleknotのスタッフの皆さんと全体テスターのhenoさん,ありがとうございました.

来年もTUPCにどうにかして関わりたいので,運営陣にまぜてください.

JAG 夏合宿 2023 参加記

9/16〜9/18 に国立オリンピック記念青少年総合センターで開催された JAG 夏合宿 2023 に参加した.

jag-icpc.org

Day 0

高速バスで仙台から東京に移動.合宿参加費 <<<<<<< 交通費 (安くしてくださってありがとうございます)

Day 1

12時半ごろにオリンピックセンターに到着.建物がめちゃくちゃでかくてびっくりした.

参加者は思ったより多くて60人くらいいた.色々な大学から人が来ていた.自己紹介のあとチームを組んだ.ICPC チームの suzukaze_Aobayama からは僕と仮の人くんが来ており,一人足りない. houren さんがチームに加わってくれて,チーム Aobayama_rHAPsody が結成された.

この日は 14:00-17:00 の3hコンテスト.全11問.韓国の国内予選2022で使われたセットらしい.

https://www.acmicpc.net/category/detail/3217

当日の順位表が見つからなかったのでどういう順番で解いたのか覚えていないが, 僕は CEGJ を解いた.CEは簡単,Gはチームメイトが考察していたのでそれを聞いて実装,Jは難しかったが頑張った.Jは面白かった.平方分割の方針で考えても何を平方分割すればうまくいくのか見えづらいし,うまく平方分割したあともそのあとどう処理すればいいのか結構考える必要がある.解けてかなり達成感があった.

結果はたしか7完?で順位は覚えていないが1桁の悪くない順位だった気がする.

解説を聞いた.HIが不可能でやばかった.韓国の国内予選ってこんな感じなんだ.この問題数を3hでやるのは大変そう.

その後部屋に行った.ルームメイトと話したり風呂に入ったりABCに出たりした後12時に寝た.次の日の朝は早い.

Day 2

7時起床.10時から5hコンテスト.この日は有志セットで,全12問.この日も Aobayama_rHAPsody で参加.

yukicoder.me

僕は後ろから見て行って,Kでそれっぽい解法が生えたので実装した.ただ投げても投げても通らない.チームメイトに救助を要請すると, (a, b) が unique でないときに壊れていることが指摘される.勝手に (a, b) が unique と仮定してしまい,それでしか動かない解法を考えてしまったので振り出しに戻ってしまった.ところがすぐに houren さんがいい感じの解法を生やしてくれたので実装して AC.5ペナも吐いてしまって申し訳ない.

Kで悪戦苦闘している間にチームメイトがACHを通していた.また,Kを通したちょっとあとにBも通る.

Dが解けた気になったので実装に移る.かなり面倒なことをする必要があって, houren さんと話しながら丁寧丁寧に書いていった.オイラーツアーを取って区間加算区間 min を頑張るのが解法だが,遅延セグ木を使いたくなって絶望していた.ここで,平方分割でサボれないかと指摘され,それを採用することに.遅延セグ木を平方分割で代用するみたいなコピペなしコンテスト特有の発想がなかったので,これはかなり勉強になった.めっちゃしゃべりながら実装したおかげでいろいろ整理できてスムーズに実装できた.チーム戦のいいところ.サンプルがあったので提出すると,一発でAC.特大のガッツポーズが出た.

それ以外は解けずに6完7位で終了.この日も悪くない順位を取ることができた.KでやらかしたがDで取り返せたのも満足.

解説を聞いた.なんかいろんな意味ですごい問題だらけだった.コピペなしのコンテストで重み付き一般マッチング想定が出たのにはさすがに笑ってしまった.

飯を食べて風呂に入って部屋に戻る.ARCまで1時間半くらい時間があったので,ルームメイトと大富豪をやった.久しぶりに大富豪やったけど楽しすぎる.潜伏して tourist 出しする人がいてウケた.僕は基本的に貧民をやっており,資本主義の残酷さを思い知らされた.

9時からARCに出る.いつもratedコンテストのときは耳栓をしているが,今日は持ってくるのを忘れてしまったという話をしたら,ルームメイトが大量に耳栓を持ってきていたので1組譲ってもらった.この日の配点は 4-6-6-7-7-8 というなんともやばそうな配点でビビっていたが,結局Dまで解けて暖まったのでうれしい.Dがかなり面白いと思った.

ルームメイトと軽く感想戦をするなどしたのち12時に寝た.

Day 3

7時起床.9:45から5hコンテスト.JAG セット.11問. Aobayama_rHAPsody.

ABが簡単らしいので,Aをチームメイトに任せてBを見る.すぐ解ける.

その後,後ろから問題を眺めていった.IJにACが出ていたので,僕はJを見に行く.グリッドでうまく動いて,パス上の文字列を並べたものと目標の文字列の編集距離を最小化する問題.編集距離の気持ちになると,グリッド上の位置と,何文字一致させたかの状態を持ってDPすれば良い事がわかる.遷移がDAGじゃないので,01BFSをする必要があるということにちゃんと気づけて,AC.

その後チームメイトがCとIを通す.偉すぎる.

Eが解かれているのでEを見る.余事象を考えると,出現した数字の集合が常に区間になるようにすれば良いことはすぐ思いついたが,立式が下手すぎて計算できない形にしかならなかった.仮の人くんに見せたらいい感じに整理してくれて,実装してもらいAC.

Kを見ていたら解けた気になる.ある頂点に行って戻ってくるという操作の性質に気づいて,頂点数の偶奇とパスの偶奇を考えれば,動的なグラフで連結性判定と二部グラフ判定ができれば良いとわかる.Offline dynamic connectivity を写経してサンプルを合わせて投げるが通らない.チームメイトにも考えてもらい,解法の正当性を検討してもらったが,考えれば考えるほど正しい.全然わからないので諦めて昼飯を食べていたら,連結性判定がバグっていることに唐突に気づいた.UFで二部グラフ判定をするときに頂点倍加をするので,そこで連結成分のサイズをみるような連結性判定が壊れていた.直したら AC が帰ってきて大喜びする.

他に解かれているのがHしかないので見る.k=1の場合はトライ木で処理できることにチームメイトが気づき,あとは平方分割して大きいやつをロリハ,小さい方をトライ木で処理できることがわかった.制約とTLに対してこの解法の計算量が重すぎるので通る気がしなかったが,ダメ元で書いてみる.サンプルを合わせて投げたらなんか通ってしまって,チームが沸いた.

残り1時間位で,残りの問題を考えてみたが全然分からなかった.

8完4位で終了.最終日にとても良い結果が出て良かった.即席のチームだが,3日間を通してチーム全員が結構貢献できたのでとても楽しいチームだった.

解説.HのTLを2secにするか2.5secにするかで迷い結局2.5secにしたらしい.2secと2.5secの間に入ったチームが1つあったと聞いて我々のことかな?と言っていた.解けなかったDFGのうち,DGはかなり大変そうで,Fは思いつきたかったな〜という感じの面白い解法だった.

解説後に解散.東北勢と夜飯を食べて深夜の夜行バスで帰った.

最後に

3日間でAtCoder含め計16時間40分のコンテストに出るというハードな体験だったが,面白い問題が多くとても楽しかった.また,多くの競プロerと知り合えたのも楽しかった.

夏合宿を開いてくださったJAGの皆さんには感謝しています.とてもいい思い出になりました.

来年は,国内予選を通過した状態で参加したい.

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を通じてありとあらゆる感情を経験した.今年は未練しかない.

TUPC2022 感想

東北大学プログラミングコンテスト (TUPC) 2022 を 3/4 (土) に AtCoder で開催した.僕は writer,運営としてコンテストに関わった.

atcoder.jp

この記事では,TUPC2022 の各問題について,僕視点の感想や裏話を書いたり,当日のオンサイト会場の感想などを書く.準備の記録などもあとで別の記事を書くかも知れない.

問題について

多くの問題が好評を頂いたようで,とても喜んでいる.また,全部の問題にACが出たのも嬉しかった.

ただ,時間に対して難易度が高すぎるという意見もたくさん頂いた.また,序盤から難しく,初心者にはかなり厳しいセットになってしまったことは否めない.これは,運営陣の難易度評価が完全にバグっていたからであり,申し訳ないと思っている*1.この辺の課題は次回には直したい.

問題順序は,writer 4人 + 全体 tester 2人 の6人で,各問題について difficulty を予想し,その平均を取って昇順に並べた.分散がかなり大きかったが,平均は正しい値になるだろうと思っていた.しかし,全然そんなことはなかった.

A - Sum Sort

いい感じの簡単枠だと思ったが,それでも結構難しかったらしい?

B - Snowy Aobayama

東北大ネタが1問くらい欲しかったので,ちょうどよい.

C - Flip Grid

解く前に解法を知ってしまい後悔した問題の一つ.AGC-Aとかにありそうな感じ?

D - Zeta Sum

tester をした.式の見た目がやばすぎる.展開してシグマを5重にするのはためらわれたが,勇気を出してやってみたら見掛け倒しで面白かった.この見た目を D に置くのはちょっと渋ったが,解法の難易度的には妥当だと思いここに置かれた.結局 D にしては厳しすぎたかも?

E - 00-11 Rotate

解く前に解法を知ってしまい後悔した問題の一つ2.解説の証明を考えた.AGC-B とかにありそうな感じ?難しいとは思っていたけど,ここまで解かれないとは思わなかった.

F - Block Rotation

writer をした.題材は「万華鏡」.2回の操作で形が揃うことと,サイクルに分解できることに気づくのがちょっと難しい?実装は,やることが多く,想定解も 100 行近く行ってしまった.とはいえ,添字を合わせたり場合分けを頑張ったりみたいな辛さはないので,実装難易度自体は高くないと踏んでいた.ところが思ったよりも解かれず,G, Hと逆転してしまった.

G - All Pairs

tester をした.考えていてかなり楽しかった.どこに辺を追加するかが本質.

H - Next Permutation

tester をした.階乗進数で足し引きが簡単にできることに気づいて,かなり感動した.階乗進数を見たことがなかったので,とても面白いと思った.僕は結構難しいと感じたが,思ったよりも解かれた.

I - Count Setwise Coprime

tester をした.僕は解法2の Mertens 関数を用いる方法で解いた.数論関数の累積和を知らなかったが,いろいろ調べたら 3/4 乗や 2/3 乗で解けることを知って勉強になった.解法1はかなりきれいだが,これは思いつかないよ.......

J - AMidA

最初,writer から「サイクルを分裂させるクエリと,2頂点が同じサイクルに属するか判定するクエリを処理する方法で,削除可能 union find よりも良い方法はあるか?」と相談をされた.調べると,グラフが森なら decremental connectivity が逆マージテクで解けるということが Wikipedia に書いてあった.これ自体かなり面白く,勉強になった.そしてこの方法がサイクルにも応用できることに気づき,この問題の構築部分の解法となった.

その後,問題自体も解いてみた.予め,サイクルを分裂させればいいということを知っていたので,割とすんなりと解けてしまった.実際は,そこに帰着すれば解けることに気づくまでが一番難しいので,自力で解けたとは言えないかも知れない.

サイクルを分裂させれば解けることも,それが逆マージテクで処理できることも面白く,かなりの良問だと思った (問題名も面白い!).思ったよりも解かれなかった.

K - Lebesgue Integral

writer をした.実は去年の TUPC2021 B - Minimum Upper Sum は, Riemann 積分を離散化したつもりの問題だった.そこで, Lebesgue 積分版でも作ってみようと思ってこの問題ができた.

高度典型やるだけ枠を出すのはちょっと申し訳ない気持ちもあったが,1問くらいあってもいいかと思って出した.最近 Universal Cup かなんかで Monge が出たらしく,Twitter で話題になることが多かったみたい.

橙中位くらいの難易度だと推定していて,実際そうなった.今回のセットで,難易度推定が正しかった数少ない (唯一の?) 問題だったかも知れない.

ところで,Minimum Upper Sum はめちゃくちゃ難しいのに Lebesgue Integral は (計算量が良いという意味で) 簡単なのだが,これは Lebesgue 積分が Riemann 積分よりも良い性質をいくつか持っていることと関係があったりするのだろうか?

L - Inversion High and Low

tester をした.最初,N=500で質問回数4000回だったのだが,マージソートの比較回数をちゃんと評価したら3990回くらいでギリギリ間に合ったので,N=100で質問回数500回になった.N=100のときの比較ソートの比較回数の情報理論的下界が 525 回なので,マージソートだとどうやっても無理になる.=の情報を必ず使わなければいけないというのが,理論的にも結構面白いポイントだと感じている.

実は自力で解けていない.最初,想定解よりも比較回数が少ない解法 (マージソートベース) を得意になって喋っていたが,あとになってすべて真っ赤な嘘だったことが発覚した.その後も,=の情報をうまく使うように工夫して,クイックソートを使わない別解をずっと考えていたのだが,全然思いつかなかった.比較回数自体が減らせても,比較の基点を取るためのクエリが増えてしまい,結局全クエリ回数が500回を超えてしまう.全体 tester や,本番中に解いた人は非想定解法で解いたようだが,彼らも結局クイックソートをしていた.マージソートを頑張る方針だとどうやっても無理なのだろうか.

この問題の準備中に,ARC にインタラクティブなソート問題 (ARC154 - D) が出て,ちょっと冷や冷やした.

この問題は本番中,最後の方まで解かれなかった問題だった.終了10分前までACどころか提出すらもほとんど無く,このまま終わってしまうのかと思っていたが,ぎりぎりで1チームだけ通してくれた.writer 陣が集まってジャッジを見守っていたが,ACの緑文字が見えたときには一同が湧いた.

M - Fractal Tree Isomorphism

writer をした.「木 (植物) はフラクタル」という話がある.木以外にも,フラクタルは自然界にあふれている.このことをなにかの本で読んでとても面白いと思い,木 (グラフ理論) でもフラクタルを作ってみることにした.木の有名問題を fractal tree に置き換えるだけなので設定はいくらでも考えられるんだが,同型性判定の解法が面白くなったのでこれにした.

自分は,まず同型になるようなサンプルを作ろうと思ったら問題が解けた.fractal tree が同型になるような木のペアは,同じ繰り返し単位を持つような2つの木を持ってくれば作れる.すると,これが必要条件になっているとエスパーできる.

直感的には正しそうだが,証明はかなり難しい.僕は,fractal tree に葉がないことが難しさの原因であると感じた.木の同型性判定アルゴリズムは,hash も AHU algorithm も葉からボトムアップに見ていっているわけだが,fractal tree は根から始めるトップダウンな議論をしなければいけない.証明を考えるのに数日かかった.また,無限集合に関する証明を厳密に記述することも難しい.集合論を思い出して頑張って書いたが,不安だったので数学に強い tester に確認してもらった.

正当性の保証が難しいとはいえ,通すだけなら黄 diff くらいだと思っていたが,あまり解かれなかった.

実は,オートマトン最小化による解法があり,想定解よりも良い計算量になるようである.これは全体 tester にも指摘された解法だが,理解が間に合わずコンテスト当日を迎えてしまった.ちゃんと理解したい.

N - Matrix Game

writer をした.かなりシンプルな条件で判定できる.実験だけでは見えにくい条件なので,考察を然るべきところでする必要がある.一方で,証明が難しいパートがあるので,考察だけでは解けそうにない問題でもある.実験と考察をうまく組み合わせる必要がある.

当初この問題は Matrix Nim という名前にするつもりだったが,一応既出チェックのために調べたら論文が見つかってしまった.問題名を Matrix Game に変えることでお茶を濁したが,結局論文の存在がバレてしまい (検索が上手すぎる!),しかも既出だったことがコンテスト中の提出から発覚した (Topcoder SRM 793).SRM 本番中に tourist が 15 分で解いていたんだがどういうこと.......これも論文を見つけたのかな?それにしても速すぎる.

コンテスト中ACのほとんどが論文または既出に気づいたものだったようだが,正面から取り組んで解いてくれたチームもあったようで嬉しかった.

O - Equidistant Binary String

tester をした.超絶難しい.ヒントを貰いつつ解いた.

実装もそこそこ難しいのだが,それ以上に考察のボリュームが凄かった.どうやったらこんな問題がつくれるんだ.そもそも,設定を思いつけたとしても自分で解法を思いつける気がしないので,この問題を自力で解けるのがとんでもなくすごい.

本番で2つACが出てびっくりした.

オンサイト会場について

特に大きなトラブルもなく,時間通りにコンテストを開始できて安心した.

コンテスト中は内職をするつもりだったが,順位表が気になりすぎて結局4時間張り付いて観戦していた.中盤や終盤の問題にも,かなり早い段階でACが出ているのがあってびっくりした.一方で,序盤のACはなかなか増えず,やばいセットにしてしまったかも知れないという雰囲気があった.

個人参加の人が上位に多かったことに驚いた.1人でやるにはかなり重いセットだと思っていたので,個人でどんどん解き進めている人を見て,すごいなあと思っていた.

順位表観戦が楽しすぎて時間を忘れ,気づいたら4時間経っていた.解説スライドを作るに当たり, difficulty を順位表から計算してくれるスクリプトを使って,各問題の difficulty を調べた.予想 diff と実際の diff の差が2色くらいあって笑ってしまった.ごめんなさい.......

解説,講評,観光案内の後,懇親をした.問題が面白いと言ってもらえていい気分になった.ARC書けるんじゃない?とも言われてさらにいい気分になった.書いちゃおっかな〜.

いろいろな人と喋れてとても楽しかった.他大学の競プロ事情とか,社会人の方の競プロ事情とか,直接聞かないと知れないようないろいろな裏話とかを聞けた.

話し込んでいて気づいたら会場を閉める時間になってしまった.懇親の時間を長く取れたので,4時間にして結局良かった気がする (オンライン参加者には申し訳ないけど).それでも時間が足りなくて話せなかった人が多かったのは残念.

最後に

あおばさんをおばあさんと言っている人は表に出てください.

オンライン参加者含め,参加してくださった方々,ありがとうございました.問題が面白いと思っていただけたら writer として望外の喜びです.

問題準備からコンテスト当日まで本当に楽しかったです.来年もやります.

*1:どれくらいバグっていたかについては,オンサイト会場で使った解説スライドを参照してください.AtCoderの解説タブから見れます

AtCoder 橙になりました

2023/2/12 の AGC061 で念願の AtCoder 橙になりました.

(ABC を除く) コンテスト中 AC の difficulty の自己ベストを大幅更新して色変出来たので,最高です.


各種記録


やったこと

問題を解く

  • 黄を全部埋める
    • いつ達成したか忘れたが,B1 の頃に達成した気がする.(今は B3)
  • 橙を 9 割埋める
    • B1 終わりの春休みに狂ったように埋めていて,このときに半分以上解いた記憶がある.
  • AOJ-ICPC を解く
    • これは ICPC 対策のためにやっていることだが,AtCoder で見る機会が少ないフロー,幾何,構文解析に強くなれる.ABC でこれらが出ると比較的スムーズに解けることが多いが,A[RG]C にはあまり出なくて悲しい

解説 AC については,

  • ABC とコドフォ: しばらく考えてわからなかったら見る
  • ARC と AGC: 基本的に見ない.解けなかったら寝かせてしばらくしたら再チャレンジ

というスタンスでいる.

考察メモをつくる

なにか学びがあるたびに,個人の考察メモに書き溜めている.コンテスト中に参照して役に立ったことはあまりないが,知識を整理したり,定期的に見返して忘れていたテクを思い出したりするのに役に立っている.

アルゴリズム・データ構造を勉強する

たまに気が向いたら Library Checker で解いてない問題を選んでそれを勉強する.結構役に立つものもあるが,マニアック過ぎてコンテストで見たことがないものがほとんど.

また,競プロサークルで最近まで組合せ最適化の輪読会をやっていた (切りのいいところまで読んだので終了).LP,マトロイド,マッチングなどの話題を知れた.LP もマトロイドも汎用性のある話題で役に立ちそうだし,なにより理論がかなり美しくてとてもおもしろかった.ただ,これもコンテスト本番で役に立ったことはない (過去問埋めでたまに使うことはある).

また,ABCやエデュフォのボス問はだいたい高度な知識を要する問題なので,たまに解説ACして知識を得ようとしている.

作問する

僕はあまりたくさん作る方ではないが,主に TUPC (東北大学プログラミングコンテスト) のために作問をすることがある.去年の TUPC でも 4, 5 問出した.今年の TUPC でも writer をやっている.

Writer や tester として,ある問題に深く関わると,その問題に使うアルゴリズムとか考え方の理解が深まるというのはあると思う.コンテストでも役に立ったりする.

(ここで宣伝)
3/4 (土) に AtCoder で TUPC2022 を開催します!今年はオンサイトも同時開催です!たくさんの参加をお待ちしています!

サークルに参加する

バチャとか,ICPC 参加とか,TUPC 準備とか,前述した組合せ最適化ゼミとか,いろいろ活動している.

活動内容そのものが競プロに役に立っているという感じはあまりないのだが,サークルを通して同じ大学の競プロ er たちと知り合えて切磋琢磨できるのが,とてもモチベーション維持に貢献していると思う.

かなり幸運だと思っているのは,近い学年に近いレートの人が数人いて,みんな結構アクティブにサークルに参加していること.ライバルがいてとても刺激になっているし,楽しい.

(最近研究室のミーティングとかぶって定例会に全然参加できていなくて悲しい)

感想

2200 周辺で停滞していた1年半,かなり苦しかった.......

ICPC が終わるたびに「来年の予選までには橙になるぞ!」と言い続けて2年,やっと届いた.

コンテスト直後は強烈な達成感,幸福感,解放感,充実感,自己肯定感,第六感,恋の予感,その他任意のポジティブな感情を感じ,全然眠れなかった.

同時に,「本当に自分に橙が務まるのか?」という気持ちもあるので,気を抜かずに行きたい.

これから

今年の目標

  • Codeforces 赤
  • AHC 黄
  • ICPC 国内 + アジアで一桁順位

AtCoder は,どこまで行けるんだろうなあ.とりあえずは来週からの2連ARCで橙を維持するところからですね.

ICPC アジア地区横浜大会 2022 参加記

チーム suzukaze_Aobayama (milkcoffee, karinohito, sotanishy) で,ICPC アジア地区横浜大会 2022 に参加した.

今回はオンサイトでできるということで,とても楽しみだった.一方で,コロナ前のICPCルール (ライブラリ写経やPC1台制限) に触れるのが初めてであり,不安でもあった.

目標は,全体10位 & 学内1位.

本番前

11/27 模擬地区
オンサイトでも開催されるとのことだったが,流石に東京は遠い.....ということでオンライン参加.数日前に本番のルールが公開されたので,それに則って参加した.US配列を使っていたのが僕だけだったので僕のパソコンを実装マシンにして,ライブラリも僕のを使うことにした.

初めてICPCルールでやってみての感想:

  • 他人の環境で競プロをするというのはかなり苦しい.みんな実行・デバッグの仕方やファイルの命名規則,マクロの仕様などが違うので,僕のマシンで実装するのは大変そうだった.
  • ライブラリの仕様の理解不足によるバグが発生したりして大変だった.また,写経ミスが多発.
  • 実装キューが詰まりまくり.バグが発生したときに,どのタイミングで実装待ちの人にパソコンを譲るべきかが悩ましい.また,実装待ちの人が手持ち無沙汰になりがち.

この辺はしっかり練習しないとな,と思った.

結果は6完16位,guestを除くと12位で,そんなに悪くはなかった.考察は割とスムーズに行って,最終的に attempt したすべての問題の本質的な考察は開始2時間程度で終わった.あとはひたすら実装キューの消化作業だったが,実装が重く,ライブラリが必要なものが多かったので,実装もデバッグも大変だった.

その後の練習

模擬地区以降,ほぼ毎週末チーム練を行った.コドフォの gym の海外 regional を中心にバチャを走った.並走してくださったチームには感謝いたします.

練習していく中で,次のような戦い方に固まってきた.

  • 実装と考察の分担は特にしない.全員がそれぞれ問題を読んで,解けたら自分で実装する.
    • 特にパソコン1台ルールだと,実装が得意な人が実装を引き受け,残りの人で考察を進めるという戦い方のほうがスムーズなのかもしれない.しかし,僕らは皆同じくらいの実力であり,得意分野も分散しているので,全員で考察したいという気持ちがあった.
  • 実装中に詰まったらすぐに離れて次の人に譲る
    • 詰まったらそのまま実装マシンを使って出力を見ながらデバッグしたくなるところだが,実装キューが詰まっているときはすぐに離れるように心がけている.マシンを使わないとデバッグが難しいのは確かだが,一旦実装から離れてコードを読むと頭が冷えてバグが見つかりがちである.ただ,本番ではコードの印刷がどれくらいのオーバヘッドになるかわからないのが心配.

ライブラリ

僕のライブラリは実装が冗長なので非常に写経しづらい.ICPC向けの簡潔な実装をした他の人のライブラリをパクってこようかとも考えたが,仕様が好みでなかったりした.結局,写経しづらくても使い慣れている自分のライブラリを使うことにした.

印刷するために,ライブラリをまとめたファイルを以下の手順で作る.

  1. 持っていくものを取捨選択する.心を鬼にして†断捨離†をする.
  2. 横浜国立大学のICPCライブラリの tex の設定をパクってくる.ありがとうございます.
  3. 選んだライブラリのソースコードとドキュメントを tex ファイルに貼り付ける.これは適当に Python スクリプトを組んだ.
  4. 手動でドキュメントをいじって微調整

2カラムで30ページ強になった.両面印刷すれば15枚程度と,結構コンパクトにまとまった.

お守りとして link/cut tree を入れた.チームに1本あると安心感が違う.

Day 0 (12/26)

この日は最後のチーム練で,2022 ICPC Southeastern Europe Regional Contest を走った.不快要素が少なくかなり楽しめ,良い感触が得られた.

夕方くらいから本番に向けてそわそわし始めた.修学旅行前夜や,部活の大事な大会前 (これは実際にそう) のような気持ちになっていた.夜は荷物や着替えをまとめたり,考察メモを印刷したりしていた.翌朝は早いので.早めの就寝.

Day 1 (12/27)

7時半ごろ起床.朝ごはんを食べて仙台駅に向かう.チームメイトと合流し,新幹線に乗り込む.新幹線では問題を解こうとしたが,画面を見ていると酔って気持ち悪くなってきたのでやめちゃった.

東京駅や横浜駅で他の東北勢と合流し,横浜駅でご飯を食べる.

カツを食べて勝つ!

腹ごしらえが済んだら会場の横浜産貿ホールに向かう.13時頃入場する.一応公式言語が英語になっているらしいので受付では英語対応だったが,スタッフも日本人なのでなんか違和感がすごかった.

suzukaze_Aobayama の席は一番後ろの方だった.これは結構当たりな気がする.会場全体を見渡せることと,後ろが気にならないというのが結構良い.席についたらICPC Tシャツに着替えて,チーム紹介ドキュメントを見たり雑談をしていたりした.

14時になり開会式が始まる.今年のオープニング動画もかっこよかった.

www.youtube.com

14:50からリハーサル.去年のアジアの問題がそのまま出るものかと思っていたが,今年はインタラクティブがあることもあってか全く違う問題が4問集められていた.印刷の手順やエディタの機能の確認をしつつ問題を解いた.全完したあとは,トイレに行く練習 (英語でスタッフに声をかける必要がある) をしたり,キーボードに慣れるために写経の練習をしたりしていた.

16:30からチーム紹介.喋りはチームメイトに任せて僕は名乗るだけだった.

終了後,ホテルに移動する.チームメイトと相部屋.同じホテルには他にも競プロerが結構泊まっていたようである.荷物をまとめたり一休みしたあと,東北勢で中華街に繰り出して夜ご飯を食べた.

↑とだいたい同じものを食べていた.もう完全に修学旅行気分です.

8時半頃またホテルに戻る.3人でAGCの赤diffを考察しないかと誘われ,AGC022 E - Median Replace を考えた.なんか3人で考察を言い合っていたら解けてしまい,感動した.

Day 2 (12/28)

朝7時頃に起床する.朝食を食べる.眠かったので軽く二度寝をする.

8時半頃に会場に着き,開始を待つ.

9:30開始.まず milkcoffee さんが環境のセットアップをしつつ,僕がA,仮の人くんがBを見る.Aは親の顔より見た貪欲だったので,セットアップが終わる前にマシンを奪い取り実装する.AC (A: 0:08)

その後,milkcoffeeさんがCから先,僕がKから前にひと通り見ていって,解けそうな問題を探す.K, J, I と見ていって何もわからね〜と言っていたところで,開始30分頃にFのACが出たことを確認したので,僕とmilkcoffeeさんでFを見に行く.

その間,仮の人くんがBのインタラクティブと格闘していたよう.WAが取れなくて大変そうだったが,通る (B: 0:45+2ペナ)

Fを考える.制約的に部分和問題になりそうなのと,何らかの偶奇がクリティカルになりそうということを感じ取る.ところが考察がそこから進まない.するとmilkcoffeeさんが,サイズ偶奇が等しい4つの集合に分けれるのが必要十分だという.これはかなり正しそうだが,そのままやると計算量が大きくなってしまう.さらにmilkcoffeeさんが,サイズが偶数で和が等しくなるような2等分の仕方を2つ持ってきて,それらの共通部分や差集合を取れば4つの集合が得られるという.これはかなり天才で,確かにこの制約で正しい答えが得られる.細かい所の正当性などいまいち理解しきれていないところもあるが,正しそうなのでそのまま実装に移る.たまたま僕が実装席に座っていたのでそのまま実装してAC (F: 1:45).Fの 3rd AC だったようだ.

順位表を見ると,D, E, G にACが出ているので,3人で手分けしてこれらを読むことにする.Dはほか2人がすでに目を通していたので問題概要を伝えてもらう.実装がつらそうだが気合で行けそうな雰囲気の問題だったので,僕がDの実装に取り掛かることにする.

実装方針をあまり固めずに取り掛かってしまったので,実装が大爆発し,途方に暮れていたところで,仮の人くんがGを解けたというので実装を渡す.その間に僕とmilkcoffeeさんでEを考える.とりあえずサンプルを手でやってなんかいい感じの性質を見つけようと思ったが,ICPC文字列を探すのが下手すぎてサンプルの理解に30分以上かかってしまった.

Gに嘘が発覚したらしく,僕がDの実装を,仮の人くんがGの実装を代わる代わるやる感じになった.

Dを書いていたところで,仮の人くんが「次の問題が解ければGは解けます.木で,一つ固定のパスがあります.クエリが飛んできて,木の2頂点が与えられるので,それらを結ぶパスがその固定のパスと共通の辺を持つか?」と聞いてくる.それは解けて,固定のパス上にない頂点について,それを含む部分木が固定パスのどの頂点から出ているか前計算しておけばよいということを伝える.それで解けたらしく,Gの実装を渡す.デバッグが大変だったらしいが通る.(G: 3:35)

コンテストも終盤に差し掛かっている.そこそこのACが出ていたDとEを通すのが現実的だろう.僕は引き続きDの実装をして,残りの2人にEを見てもらう.

Dは流石に落ち着いて方針をちゃんと定める.4回転全部試し,x方向のシフトを全探索する.y方向のシフトは定数個の候補しかないので全探索する.シフトを固定したら,マス目を一つ一つ見ていって,oを取り除く場所と付け加える場所が1つずつあるかどうか調べる.この方針でやることにした.それでも実装はかなり大変である.

仮の人くんがEを見た瞬間解けたらしく (は?),僕がDをやっている間に紙コーディングまで済ませてしまったらしい.Dで詰まったタイミングでEの実装を譲る.実装して少々デバッグし,提出する.計算量が結構ギリギリな解法らしく,提出後数分はジャッジ結果が帰ってこずヒヤヒヤしたが,Correct Answerが返ってきてチームが沸く (E: 4:39)

さて,あとはDだけである.これはなんとしてでも通したい.実装を終わらせ,デバッグをしばらくすると,サンプルが合う!一応自作ケースも試しておこうと,僕が実装していた間に作ってもらっていたケースを入力する.落ちる!困った.

原因がわからないまま残り1分になり,自作ケースがテストケースに入っていないことを祈って提出してみたが,Wrong Answerで終了.

5時間あっという間だった.

EFGが通ったのはなかなか良い結果であったと思うが,Dが通せなかったのは非常に悔しい.また,EFGに関しても僕はあまり本質的な貢献ができなかったので,少し残念だった.

閉会式.スポンサーの方々のありがたいお言葉を拝聴したあとは,解説である.去年よりは簡単な問題を用意したつもりだと言われたが,そんなことなくない?まあ高難易度のあたりはどちらにせよ解かないので知らないが,中盤の問題は去年よりも大変な感じがした.Dはうまい方針があるのかなあと思っていたが,解説でも場合分けが想定で,単に気合が足りなかっただけかなあ.Fはかなり難しい想定だったらしく,すんなり解いたmilkcoffeeさんがすごい.Jはかなりシンプルで面白い.Cはあまりにも天才.Hは,仮の人くんが得意そうな問題で,ちゃんと読んでいれば解けたかもと悔しがっていた.でも,あの順位表でHに行くのは勇気がいるよなあ.......Iは不可能.

待ちに待ったYes/Noの時間である.結構なチームが凍結後に通していて,僕らの順位が大きく下がったりしないだろうかと心配だったが,5完内で上の方に残れたので結果は13位.最後Dを通していたとしても,6完最下位になりそうだったので,順位は1位しか変わらなかったようだ (それでも通したかったが).

その後懇親をし,東北勢と打ち上げをして解散した.

振り返り

個人的には結構冷えた感覚だったが,13位というまずまずの成績を収められたのは,F,Eをそれぞれ爆速で解いてくれたmilkcoffeeさんと仮の人くんのおかげだ.今回はただただチームメイトに助けられた.

PC1台の特殊なルールの中でもそれなりにうまく立ち回れたという感覚はある.詰まったらすぐ印刷して実装を譲るというのはちゃんと練習してきたし,今回もそのへんは本番でもスムーズに行けたと思っている.実装キューもあまり詰まらなかった.

今回のコンテストでは,考察力だけでなく,実装力の不足を痛感した.実装力というのは単に長い実装を素早くやるだけではなくて,バグりにくいコードを書く力,実装が楽な方針を選び取る力.特にPC1台ルールではデバッグの速度が非常に重要だと感じた.

最後に

コンテスタントの方々,スタッフの方々,素晴らしいコンテストをありがとうございました.

Aobayama_dropout の方々にもとてもお世話になりました.入学時からの憧れのチームだったので,同じ舞台に立てたことはとても光栄でした.結局今年は最後まで勝てないまま終わってしまい,そしてこれから先戦うことがかなわないのは残念であります.お疲れさまでした.

そしてチームメイト,コーチ,ありがとう.

来年はもちろん学内1位で国内予選を突破したい.dropoutがいないとはいえ,東北大には他にめちゃくちゃ強いチームがいるので,うかうかしていられない.dropoutがいなくなっても見ごたえのある東北大を目指します.

ICPC 国内予選 2022 参加記

チーム

今年も suzukaze_Aobayama です.

  • karinohito: 数学,発想ゲー担当
  • milkcoffee: 今年加入.最適化,DP,大量の作問ストックで問題を爆破する担当
  • sotanishy: データ構造,グラフ,幾何,構文解析,重実装,知識ゲー担当

去年のチームメイトだったむげんさんは今年はコーチとして参加してくれます.参加登録とか大変そうでしたがありがとうございました.

目標

国内10位

正直アジア行ければ何でもいい.

本番前

去年は国内前にACPCやKUPCなど有志コンが多くあったのでチーム練の機会はたくさんあったが,今年はあまりそういうのがないので,自主的にバチャをたくさん走る.本番1ヶ月ほど前から毎週末集まり,Codeforcesのgymにある海外regionalを中心にバチャをやった.練習では非常にうまく行っていたと思う.チーム戦がかなり上手にできていた感じがある.やっぱりチームメイトの得意分野がはっきりしているとやりやすい.

模擬国内に出る.ABCDEG6完,全体8位(guest除く),学内2位.序盤早解きで時間を稼いで,高難易度をじっくり時間をかけて通すという理想的なムーブができたと思う.

本番一週間前に模擬国内2019を解いたが,これも7位相当といい感じだった.

本番も,練習通りのパフォーマンスが出せれば確実に上位を狙えると思っていた.

当日は,14:30に参加場所に集合する.今年も顧問の先生に部屋をいくつか用意していただいた.suzukaze_Aobayamaは去年と同じ部屋を得る.むげんさんが来てくれていたのでちょっと話した.去年みたいな戦いができればいいねみたいな話をした気がする.

リハーサルをやる.僕は幾何担当なので鎖中経路をやる.昔解いたことがあるのでリハーサル終了の15:00までに間に合うだろうと思っていたが,バグらせまくってサンプルがあったのが終了2分前.提出するとWAが帰ってきて終了.よく見たらサンプルあっていなかった.

コンテスト前の微妙な時間を埋めるために,AOJ-ICPC 100~300点の問題を適当に集めて40分位の軽めのバチャをやる.本当に軽めのつもりだったが,点数が低いとはいえ実装が重いやつばかりなので大変だった.まあいい感じの時間つぶしにはなった.

バチャが終わって,本番30分前.流石に緊張してくる.この時間の記憶があまりない.

本番

始まる.今年はちゃんと定刻通りに開始.

A

milkcoffeeさんが4:38でAC.

B

仮の人くんが18:24でAC.

先にCが通っていたのでBが通った時点で3完5位.最序盤の早解きに成功し一安心.また去年みたいな流れになることを期待する.

C

僕がみる.雑に言うと,正整数 \(n,m\)が与えられるので,\(k\)を勝手に選んで \(\sum_{i=1}^k a_i=n,\,\sum_{i=1}^{k+1} b_i=m,\,a_i,b_i>0\)のもとで\(\sum_i a_i^2 - \sum_i b_i^2 \)を最大化する問題.\(\sum_i a_i^2\)の方は大きくしたいのでできるだけ一つに集めるのが良くて,\(\sum_i b_i^2\)の方は小さくしたいのでできるだけ均等に分けるのが良いというのはよくある話.じゃあ\(k=1\)で良いんじゃないかと思って実装してサンプルに対して走らせるとだいたい合うけど微妙にずれる.え,じゃあ無理です,と言いそうになるが,よく見ると \(n,m<10^6\) なので\(k\)が全探索できる.本当にこれだけでいいのか不安だが震える手で提出するとなんと通る.去年や一昨年はCがひたすら面倒だったので,こんなにすんなりCが解けるのは初めてだ.10:05でAC.

D

D, Eを得意分野に応じて割り振る作戦だった.Dが数え上げだと聞いた瞬間仮の人君に投げて僕とmilkcoffeeさんはEに向かう.仮の人君が問題を見てすぐ「これは解けます」と言っていたので託す.

1時間ほど僕はE, Fを見ていたが,Dの音沙汰がないので見に行くと難航していたらしい.大体の方針は立っているが微妙に合わない.僕も問題を見て考えてみると,番号の小さい人間から順に見ていって使う/使わないを確定させていく解法を思いつく.ただこれは\(O(n)\)で,\(n < 10^4\)という制約を全く使い切っていないので正しい気がしない.でもサンプルがあってしまったので一応投げてみる.落ちる.よく見ると,サンプルが合うことが不思議なレベルのミスを犯していた.直して再びサンプルを合わせ,出そうとするが,仮の人君がhackケースを送ってくる.走らせてみると落ちる.出さなくてよかった.......

これはかなり沼になりそうな予感がしたが,仮の人くんの方で実装していたやつがいい感じになったらしく,提出したら通った.1:59:37.

3完してからまったく進展がなく焦りも出てきて苦しいときだったので通してくれて本当にありがとう,という気持ち.

E

Cを解いてすぐ僕とmilkcoffeeさんがEを一緒に見る.構築問題.\(n \times m\)のグリッドの各マスに +1, -1を書き込んでいき,指定された行/列が括弧列として成り立つようにし,それ以外の行は成り立たないようにする.ARCにありそうな見た目.

しばらく考えてみたが全く方針が立たない.データ構造やフローには見えないので,何らかの天才をする必要がありそう.ただそういうのは僕はあまり得意ではないのでちょっと嫌な気持ちになっていると,milkcoffeeさんが天才をして,「端だけ適当に埋めて中は市松模様で埋める」という方針が立つ.端を適当に埋める,というのが可能かどうかは置いておいて,かなり筋が良さそうだし,それができなかったらもう解けません,といいたくなるくらい良い性質が見つからなかったので,しばらくその筋で考える.

1の行/列の始まりと終わりは自明に埋まる.四隅は適当に場合分けすれば埋められる.残りは,+を貪欲に左/上に詰めていけばいいのではないか.ヤバそうなケースがありそうな気はするが,もうちょっとちゃんと考えるとこのようにすれば0の行/列が括弧列として必ず壊れるようにできることが示せた.考えれば考えるほど正しい.実装をmilkcoffeeさんに託して僕はFを見に行く.この時点で開始1時間も経っていなかったんじゃないか.

しばらくFを考えたりDを見に行ったりしていてEに戻ってくる.実装が炎上していたらしい.僕の中では実装のイメージができていたので並列で実装してみる.\(n,m\)を間違えそうなので気をつけて丁寧に実装する.サンプルが合うので投げる.落ちる.よく見たら\(n,m\)を一箇所間違えていた.直す.このとき流石に学習してすぐには出さず,ちゃんと自作ケースを合わせたり,小さめのテストケースを目で見ておかしいのがないか探す.おかしいのが大量に見つかりました.四隅の場合分けを雑にやっていたのでおとなしく16通り場合分けする(実際に書いてみると本当に考えなければいけないのは7通りとかになったのでそこまでひどくはなかった).今度こそサンプルや自作ケースなどがあったので投げる.また落ちる.途中milkcoffeeさんの方でも何回かサンプルがあったらしいので何回か投げたが全部落ちる.

解法の大筋が正しいことは確信していたのでめちゃくちゃ細かいところで考察漏れがあるか実装ミスだと思うのだが全然わからない.

思い返せば,僕のコードの出力とmilkcoffeeさんのコードの出力を突き合わせてdiffを見るとかやってみればよかったのかも知れないが,あまり冷静になれておらず最後の方は微調整して投げるを繰り返してペナを重ねるだけになってしまった.

結局通らなかった.

F, G, H

Fは,Eと行ったり来たりしながらちまちま考えていたが手がかりが全くつかめなかった.Dを解いた後仮の人くんもちょっと見たらしいがやっぱりわからず.

Gは一瞬目を通したが流石にE, Fを先に通す方が堅実かと思い考えていない.Hは見ていない.


気づいたら終わってた.

本番後

結果は26位,学内2位,アジア進出

めっちゃ冷えた感覚だったので,僕らの上に Aobayama_dropout 以外の東北大のチームがいませんようにと祈りながら順位表を上から見ていったが,僕らが学内2位で本当に安心した.そのまま下にスクロールしていったら同じ4完に東北大があと2チームいることを知って驚愕した.本当に危なかった.Dを通してくれて心から感謝.

隣の部屋で出ていたSeiryo_blockerの人々と焼き鳥を食べたりダーツをしたりして遊んだ.milkcoffeeさんがダーツうますぎ.

振り返り

Cまでは順調だった.D, Eも,問題の担当は最適解だったと思うんだけど,コンテスト中の立ち回りは反省点が残る.

あまり気持ちの良い通過の仕方ではないが,通過できたことには変わりない.コンテスト終了直後は悔しい気持ちが強かったが,1日経つとまたアジアに行けることが素直に嬉しいと感じられるようになった.去年の国内・アジアや模擬国内の成績だけ見ると,勝って当然のチームであるのかも知れないけれど,不安が強かったし,だからこそ本気で準備してきたので通過して本当にホッとした.

アジアは橙橙黄で出たい.チームメイト,よろしくおねがいします.

今年のアジアはオンサイトでできるといいですね.