ICPC Asia Yokohama Regional 2023/24 参加記 (segtree 視点)

チーム

Speed Star (noimi, SSRS, ynymxiaolongbao)

どうしてこうなっているかというと、学内のAtCoder四~五段くらいの勢力(伝われ)が決まった3人組でICPCに出がちであるためです。

コンテスト前

コンテスト一週間くらい前に何か「自分が勉強しておくと良いものはあるか?」と聞いたらnoimiさんに「マトロイドとか?」と言われたので、マトロイドを勉強する。twitterで検索するとICPC作問陣にもいるYYさんやoptさんがマトロイドや劣モジュラ系を推していることが分かり、ますますやらないといけないなとなる。(実際にJ問題はYYさん原案のマトロイドだった。本番ではnoimiさんが「凸だから貪欲ができて」と言って解いていた。自分はマトロイドであることに気付いていなくて、解説を聞いて、その後の懇親会でYYさんに直接質問してやっとマトロイドであることを理解した。)

コンテスト結果

結果:全完(11完)4時間0分 ペナルティ無し

順位表

コンテスト中

・すべて時系列に書いていて、太字はその時刻にACした問題と実装者、問題概要です。

・すべてsegtree視点で書かれています。また、SSRS/noimiが何をやっていたかは微妙に違う可能性もあります。

初動

segtree: PCを触る(ログイン,エディタ立ち上げ,コンパイルコマンド設定など)

noimi: segtreeが準備してる間にA,Bを読んで解いておき、終わったら書き始める

SSRS: C以降のすべての問題を読む(←10分でできるらしい)

 

PCを触り終わって、すべての問題を眺める。

A(0:08) 実装noimi YOKOHAMAを作れ

すべての問題を読み終わったSSRSにどうするか聞くと、FとDが簡単で、「FをやるのでDを読んでください」「区間DP」と言われる

noimiがBの読解で詰まったので、SSRSがFを書き始める。

F(0:12) 実装SSRS グリッドで市松になるやつ

Dの問題を理解して、解けたので、疑似コードを書く。

noimiとSSRSが相談してBが解決した。実装はSSRSがやるらしい。

noimiがHを解いて、実装に移る前のSSRSに説明している。

B(0:25) 実装SSRS(?) 列を分割するやつ

Dを書き始める。10分くらいで書き終わって、サンプルを試すと、変な答えが出てきた(具体的には、正解が "3(ab)5(a)"  の所で、"a"と出て来た)。こんなの直らない訳がないんですよね~(笑)と思っていたら、SSRSに「大丈夫!?!??」と聞かれたので、「大丈夫じゃないです」と言い、コードを印刷してPCを渡す。

多分このタイミングでSSRSがG、noimiがEを解いていた。

noimiがHの実装を始める。自分は印刷したコードを見て間違いを探す。Hの式とかを詰めるのにたまにPCが開くので、そこで直していく(直したら今度は答えがinfになってしまった。悲しい。)。そういうことを何回かやると、サンプルが合った(本質的なミスは、区間DPをrep(r,n)rep(l,r)にしていたこと)。申し訳ない。

D(0:53) 実装segtree 区間DP

進捗表(各問題の所感、解けたか、ACしたかなどを管理している表)を見ると、この時点で

・ACした:A B D F

・解けた:E G H

・解けてない:C I J K

になっていた。

分野としてCに998、IとKに幾何と書いてあって、それはnoimi/SSRS担当なので、Jを見ることにする。

Hの実装が終わったらしい。

H(0:57) 実装noimi 燃やす埋める

Jを考える。DP高速化とか貪欲(想定解のではなく、山登り的なもの)とかを考えていた。

E(1:10) 実装noimi O(2^n*m)

Kが初めて台湾のチームに解かれた。noimiに「Jは知識の可能性があるからK見てくんない?」と言われたので、Kに移る。

G(1:14) 実装SSRS カードの枚数が5/6倍になる998

ここで実装キューが空になった。7完していて、順位表を見ると2位は5完だった。

暫くの間、SSRSは多分C、noimiは多分Jを主に見ていた。

noimiに「Kはどう?」と聞かれ、そこから3人でKについて話す。

色々話しているうちに、SSRSが「1ずらすと算数でできる」と言って、それで解けた(線分が聞けることを使わず直線のみで解いた)。

SSRSがKの実装を始める。

noimi/segtreeでJを考える。暫くするとnoimiが解けて、解法を聞いた(HLDを使う貪欲の方)。合ってそう。

この時点で進捗は

・ACした:A B D E F G H

・解けた:J K

・解けてない:C I

になっていた。

CとIはどちらもこの時点ではどこにも解かれていなかった。いつもの"難問"しか残ってない状況になってしまった。

Cは998のn=3e6でFPS感があり、not for meなので、Iを見る。

K(1:47) 実装SSRS 円の場所と半径を当てる

Jを実装するにあたって、ei133333's libraryのHLDの変数の命名規則がnoimiと微妙に違って書きにくいらしく、SSRSが空でHLDを書き、noimiがその他を書くことになった。

Iを考える。noimiがベクトルで幾何的に考えていたので、自分は濃度の方針で考えることにした。二人が実装している間に解法が分かった。証明はしっかりはしていなくて、書き下せないが可能そうという感じだった。

J(2:13) 実装SSRS+noimi 木でコストが個数の二乗の最適化

二人にIの解法を説明する。SSRSはいつも通り「本当に!?」と言ってきて安心した。noimiが「実装そんなにかからなそうだしとりあえず書いてみよう」と言って、noimiが書き、残りの二人がそれを後ろから眺めて指摘を入れる体制になった。サンプルが合って、提出すると、通った。嬉しい。

I(2:34) 実装noimi 液体を混ぜるやつ

この時点で進捗は

・ACした:A B D E F G H I J K

・解けた:

・解けてない:C

になっていた。

Cは、ポリアの数え上げ定理で周期ごとにした後、周期2なら(縮約後)回文であることまで考察が進んでいた。すぐに、周期任意でも回文であることが示された。

その後は、カタラン数の母関数が~という話になってよく分からなくなったので、modintのライブラリを写経し、サンプルで遊んだりしていた。

二乗logが分かったらしく、noimiかSSRSが書き始める。それを眺める。サンプルが合った。

オーダーを落とすための議論が始まったので、眺める。

移項とか変数変換をすると畳み込みの形になってオーダーが落ちたらしい(?)

二乗logのコードをnoimiやSSRSが一箇所ずつ書き換え、その度にサンプルが合い続けているか確認する。オーダーが落ちている。

最後の確認になって、懐に温めていたn k=1 1を言うと落ちて、k=1の例外処理が追加された。

C(4:00) 実装noimi+SSRS 括弧列的なのの数え上げ

noimiが「凍結間に合わなかった~」と言っていた。

場所が出口近くだったので、弁当を食べるとトイレに来たチームに全完したとバレるかもと心配したりもしたが、お腹がすいていたので食べた。

全問題の復習と反省をした。

segtreeがDに時間がかかったので、代わりにnoimiがどれくらいで書けるのか試したりしていた。noimiがそれを提出しようとしたが、resubmissionで変なことになったら怖いということでやめた。

あとは順位表を見たりしていた。

 

振り返り

二人が爆速であるとはいえ、自分が一番早く考え始める問題というのは必ずあって、それが早く解けてれば結構タイムが縮まるし(失敗例 K、成功例 I など)より難しいセットなら完数にも寄与するはずなので、自分は変な高難度に特化しようとするより普通に実力を上げるのが良さそう。

深層強化学習でウマ娘をやってみた

大学の課題として、ウマ娘を単純化したゲームに深層強化学習で取り組みました。

注意事項

  • コードは公開していません。
  • 実際の育成でトップ争いの役に立つようなものではなく、プレーの自動化などには寄与しません。
  • 実際のウマ娘ではなく、URA育成シナリオから更に色々な要素を削ったものに取り組んでいます。ここでは「単純ウマ娘」と呼んでいます。
  • 私が初めて深層学習を動かしてからまだ一週間経っていません。技術の周りでおかしい所などの指摘は歓迎しています。

受験不合格までの道

理科I類を受けて落ちました。

原因は、学習の遅れと、独習の能力がそこまで無かったことだと思います。

駿台お茶の水校のスーパー東大理系演習コースというところに行きます。

 

経緯

高二まで

勉強は、学校や塾の授業を聞くだけだった。ただ、高二くらいになると数学・物理・化学・古文は聞いてもあまり分からない。また高二の時は、部活をやらざるを得ない環境を作るために勉強をしないことを目標にしていて、週一で英語の塾に行く以外は勉強をしなかった。

英語:中二から塾(復習や宿題はあまりしていない。)

数学:中三で塾で数IAIIB、高一で塾で数Ⅲ(宿題や復習はあまりしていない。一応ひととおりやったが、高三になるまでに忘れた)、競プロの恩恵で組み合わせはできる

国語:返り点を打てる小学六年生状態

物理:ただの小学六年生(赤点のまま進級)

化学:元素記号が書ける小学六年生状態

生物・地学・社会:暗記が得意だったので、得意科目だった。できないものこそやるべきだと考え、物理・化学選択の理系にした。

 

高三

勉強を始めた。

英語だけ塾に半分参加し、他は参考書で自習して、たまに高校の同級生に質問していた。高校の物理・化学を一年で速修する塾のコースがあったが、よく分からない記号と概念が沢山出てきてついていけなくなったので、両方5回目くらいでやめた。

四月 展開・因数分解・式と証明の勉強をした

五月 残りの数学IAIIBの勉強をした

六月 化学基礎の勉強をした

七月 数Ⅲの微分複素数平面・物理基礎の力学の勉強をした

八月 力とは何か考えていた

九月 物理基礎の勉強をした

十月 物理基礎の勉強をした

十一月 力学・無機化学の勉強をした

十二月 東大物理演習・東大化学演習という講座を受けた

一月 共通テスト国語・漢文・波動・有機化学の勉強をした

二月 有機化学無機化学・理論化学・熱力学・数Ⅲの積分の勉強、数学の過去問(一年分)と理科の過去問(二年分)をやった

 

本番

メンタルや体調は良かった。休憩時間や帰りは同じ受験室のメンバーと話していた。

 

数学:

1. 通過領域 解けた

2.平面 (1)

3.微積分 (1)

4.整数 (1),(4) (2),(3)をずっと考えていたら時間が終わってしまった

5.微分 一回だけ微分した 

6.整式 (1)

 

物理:

1.力学 16点(?)

2.電磁気 2点(?)

3.原子 18点(?)

 

化学:

1.有機 9点(?)

2.理論 9点(?)

3.無機 0点

 

点数は下に貼ってあります

感想

数学は、教科書とサクシードだけでは解きにくいセットだった。

他は健闘した。

 

高三になってから高校範囲を始める人へ

読者の中に存在するかわかりませんが、アドバイスを書いておきます。

一般的に言われていることに近いです。

 

・理科の深いことを考えていると大変。例えば、「力とは何か?」など。

・速くやる必要があるからといって、例題を飛ばすと逆効果。

・全然勉強してないのに模試で解けてしまっても、その分野はもう大丈夫という訳ではない。

・強い同級生に聞きまくると良い。高三なので、周りはみんな強い。

 

成績

↓開示(合格者最低点は333.2667点)

f:id:Segtree:20210313224605j:plain

 

↓東大理系形式の試験の成績

f:id:Segtree:20210313171114p:plain

 

↓共通テストの成績

物理補正+5、化学補正+4

傾斜で768/900(85.3%)

f:id:Segtree:20210313185145p:plain

 

 

JOIopen2020

結果

100+100+100=300pt

1stタイ

f:id:Segtree:20200906215032p:plain

問題

A Furniture: グリッドグラフの頂点が関節点か判定して、そうでないならそれを削除するクエリを処理する問題。できるだけ左下を通るようなパスとできるだけ右上を通るようなパスを管理すると、dfsの計算時間が償却されてO(HW)で解ける。難易度10

B Monochrome: 白と黒がN個ずつ並んだ円環で、白と黒をペアにして交差数を最大化する問題。白と黒の順序は崩さずいくつかずらしたものの中に最適解があって、最適なずれの位置は二分探索で求める。時間O(Nlog^2N)で解ける。難易度11

C Power: 木の最適化問題。木DPをすると解ける。難易度8

経過

f:id:Segtree:20200906220109p:plain

 

時間は分の一の位を四捨五入していることがある

 

13:03-(0+0+0=0)

コンテスト開始

Aを読む。

読解verifyのため小課題1の5点を取る。

13:10-(5+0+0=5)

小課題2が95点で、取った方が良さそうなのでこれを考える。

一般のDAGに拡張して考えると到底解けなさそうに見えたので、グリッドグラフの優位性を考えると、グリッドグラフが持っている「左下に行けば行くほど左下に行きやすい」という性質が使えることに気づく。

この手のオリジナル感のある問題は下手に実装すると合わないので、丁寧に方針を固めてから実装し、100点を取る。

14:20-(100+0+0=100)

Bを読む。特定の二つの区間の関係を考察し、最適解の形を限定する。行き過ぎた限定をした解法を提出し、0点。verifyのため小課題1の全探索を書き、4点を取る。

15:20-(100+4+0=104)

4点の解法によるジャッジを作り、0点の解法の穴を発見する。

小課題2のためO(N^3)のDPを書くが、書いている途中で持つべき状態量が不十分だと分かる。

行き詰まったのでCに移る。

15:30-(100+4+0=104)

Cを読む。愚直に木DPを書くと、100点が得られた。

15:50-(100+4+100=204)

Bに戻る。小課題2のためのDPに最適解の形の限定を利用することを考えると、区切りの場所を一箇所決めればBITを使って解けることが分かる。O(N^2logN)の解法を提出し、35点を取る。

16:50-(100+35+100=235)

区切りの場所ごとに決まった値の最大値を求める問題なので、単調性や凸性を利用することを考える。実験をすると、f(k+1)-f(k)がk=[1,n)の範囲で++...++--..--のようになっていることが分かる。二分探索でその境界を求めるO(Nlog^2N)の解法を提出すると、100点が得られた。

17:10-(100+100+100=300)
18:03-(100+100+100=300)

コンテスト終了。 

感想

満点が取れて嬉しい。

APIO2020

結果

100+100+26=226pt

日本5th(unique)

全体43rdタイ

Silver Medal

f:id:Segtree:20200906205827p:plain

問題

A Walls: 複雑さを追い求めただけの問題。mod × indexの平面に図示すると貪欲法になる。難易度10

B Cities: グラフの性質の問題。連結成分に関する条件になって、永続ufやHLD+parallel binary search(後者を使った)で解ける。難易度11

C Tour: 木の性質のインタラクティヴ。直径を取り続ける。難易度11

経過

f:id:Segtree:20200906205850p:plain

 

時間は分の一の位を四捨五入していることがある

 

10:02-(0+0+0=0)

コンテスト開始

Aを読む。条件が複雑で、それを整理する。

読解verifyのため小課題1,2の12点を取る。

10:40-(12+0+0=12)

眺めていると解けそうだということがわかる。

複雑な条件の扱いに時間がかかる。

Dijkstraを書くと、最後の小課題がTLEして、63点を取る。

11:30-(63+0+0=63)

よく考えるとDijkstraは必要なくて、貪欲法で解けることがわかる。

実装して100点を取る。

11:40-(100+0+0=100)

Bを読む。これも条件が面倒で、それを整理する。

読解verifyのため小課題1の6点を取る。

12:00-(100+6+0=106)

小課題2を考える。見落としで時間を使う。追加で7点を得る。

12:20-(100+13+0=113)

愚直の小課題3,4を書く。50点を取る。

12:40-(100+50+0=150)

満点に対するクエリの平方分割解を思いつく。TLEする可能性があり、実装も重いので、別解を思いつく可能性も考えてCに移る。

12:50-(100+50+0=150)

Cを読む。直径を繰り返し取れば良いことが分かり、小課題1,2の26点を取る。

13:30-(100+50+26=176)

小課題3の二分木のケースを考える。構築的な解法を考えたが、実際はプログラミング的な解法だった。小課題4には変な制約が付いていたが、真意が掴めなかった。残り時間が少なくなったので、Bに移る。

14:30-(100+50+26=176)

Bの満点を考えると、HLD+parallel binary searchで解けることが分かる。実装して、木のケースの小課題5に正解し、追加で23点を得る。

14:50-(100+77+26=203)

最後の小課題の小課題6は一般グラフのケースで、最小全域木を取ると木のケースに帰着できる。残り1分のところで提出し、100点を取る。(結果は見えていない)

15:01-(100+100+26=226)

ジャッジを見守る。

100点が返ってきて安心する。

15:02-(100+100+26=226)

コンテスト終了

 

感想

APIO2019は、開催日が土曜日であるところを日曜日と勘違いして参加できなかった。

APIO2020には参加できて嬉しい。

JOI春合宿2020Day3

結果

35+0+15=50pt

日程内9位(unique)

累計8位(unique)

f:id:Segtree:20200322171330p:plain

A:ヒストグラムの木の問題、難易度12(?)

B:なもりグラフでクエリに答える、難易度12(?)

C:木の辺を彩色して根に案内する、難易度10

経過

□9:00(0+0+0=0pt)

コンテスト開始

Aを眺める

走査方向を高さの昇順に取ると良いことがわかる

うまく扱うと木になりそうだということがわかるが、O(N^2)のDPでA-1,A-2を通しておく

□10:00(35+0+0=35pt)

A-満点を木DPで解くことを考える

実装して何回か提出するがWA

ある区間の星によって孫以下の区間が分断されるケースを見落としていることに気づく

難しい問題であることがわかるので、別の問題に移る

□11:15(35+0+0=35pt)

Bを読む

危険なデータ構造と場合分けを求めているような見た目をしていて、小課題の点数も低いので考えないことにする

□11:16(35+0+0=35pt)

Cを眺める

C-1,C-3の値が3までの木のケースを実装する

入力形式を誤認していたところを修正する

□11:43(35+0+4=39pt)

C-2,C-4の一般グラフのケースを考える

根への単なる到達を達成する解法をdfs木で実装し、サンプルが合わなかったため、最短路での到達が求められているということを理解する

BFS木を書いて追加の11点を得る

□12:09(35+0+15=50pt)

C-満点を考える

パスのサブタスクを考え、どの点から見ても左右非対称な6文字の2進文字列を見つける

ウニのサブタスクを考え、次数が3以上の頂点では根に近い辺だけが別の色だとわかる

丁寧にレジュメを書いて実装するが、WA

□13:22(35+0+15=50pt)

直前の辺と頂点の扱いの周辺で条件式や応答形式などの間違いがあった

提出&assertなどのデバッグをするが、0点のまま競技が終了する

□14:00(35+0+15=50pt)

考察

求められていることを確認して、正しいコードを書こうという姿勢が必要

エスパーした怪しい解法を雰囲気で実装して正解できるのはAGCだけ