【色変記事】レッドコーダーになりました!
2023年9月8日の World Tour Finals 2022 Day1(Open Contest)をもちまして、レートが赤に突入しました!!!
レットコーダーになりました!!!!!! pic.twitter.com/3sVTYGSX31
— りーふ@競プロ (@leaf_1415) September 8, 2023
のでいっぱい自分語りして気持ちよくなります。
1年目
2017春 競プロに出会う
大学で競プロをやる授業があったのをきっかけに競プロに遭遇。
形式こそはコンテストであったものの、授業なのでそんなに難しい問題は出ません。
が、授業で最難レベルの問題「各マスが白か黒で塗られたグリッドの黒い連結成分の個数を数えよ」は当時の自分には歯応えのある難易度でした。
国際大学対抗プログラミングコンテスト(ICPC)というものがあるというのを多分授業で教えてもらって、過去問が難易度別にまとめられたサイトを見つけました。
グリッドの黒い連結成分を数える問題はどれくらいの難易度かなと調べたら、100〜1200の難易度評価のうちなんと150しかなく、じゃあ400~500くらいはどれくらいかと見てみます。
「500円玉貯金」
https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1603&lang=jp
全探索くらいは書く能があったので書いて提出しますが、当然(?)にもTLE。こんなのどうしたらいいんやという感じですが、「動的計画法」でこれは解けるらしい。
「ダルマ落とし」
https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1611&lang=jp
こんなもん解けるわけ………ホンマや!(出っ歯)
世の中には僕の知らない難しい問題がいっぱいあって、どうやっても不可能にしか見えない問題が、解説を見たら魔法みたいなカッコいい方法で解けるのに魅了され少しずつハマっていったのです。
チーター本を読む
「最強最速アルゴリズマー養成講座」、いわゆるチーター本が大学図書館にあったので借りて読みます。トップクラスのプレイヤーはレッドコーダー(←後に私がなるやつ)と呼ばれて恐れられている(?)らしい。レッドコーダーというのはとにかくすごいらしい(←後に私がなるやつ)。
本で紹介されていたTopCoderに登録するも環境の都合か重くてストレスフルだったのですが、そういえば友人のT君がAtCoderというのをやってたなあというのを思い出して登録します。
AtCoder始める
2017年6月3日「AtCoder Regular Contest 075」に初めて参加。
当時は、ABCとARCが同時開催で、ABCがA,B,C,D問題を、ARCがC,D,E,F問題をカバーする形式でした。結果はCの1完。
ICPC2017国内予選
友人のT君、H君とICPC2017国内予選にチームtojimboで参加。
結果は1人1問ずつ解いて3完。Cまでは実装さえできれば良いもののDからは計算量を意識する必要があって難しい。3人にコンピュータ1台というのも結構大変。
予選通過はなりませんでした。
蟻本購入
2017年7月24日にAmazonで蟻本が届きました。
ここから8ヶ月くらいかけてゆっくり読んでいきます。初級編でも1回読んだだけではわからないところも結構あったのですが、周回するごとにわかるようになっていき、読むたびに発見がある本です。(たぶんいま読み返してもまだまだたくさん勉強になりそう)
コンテストの際は近くに置いておいて、考察の際にパラパラめくってはこの世にはどんなアルゴリズムがあったっけなと参考にしてました。
CODE FESTIVAL 2017 qual A 通過
2017年9月23日 CODE FESTIVAL 2017 qual A
なんか予選に通過したら東京の本戦に招待されるらしい。
問題との相性に恵まれ僕だけが解ける天才パズルが出てなんと通過!
しれっと入青
DISCO presents ディスカバリーチャンネル コードコンテスト2017 予選通過
2017年10月7日に参加した「DISCO presents ディスカバリーチャンネル コードコンテスト2017 予選」に通過!!
のはずが、通過メールがGmailのプロモーションのカテゴリに入っていたのに気づいた時には返信期限を過ぎていました。うんち。
入黄
2017年11月11日 人知れず入黄
CODE FESTIVAL 2017 本戦
2017年11月25日秋葉原UDX(?)みたいなとこで本戦!
日本人80人と海外勢20人の計100人で1泊2日で競プロづくしをやるすごいイベント
結果は惜しくも98位
chokudaiさんによる各問題の生解説があり、1000点問題とかの解説を聞いて、これが1000点問題かすげ〜〜〜ってなった記憶。
他にもトッププレイヤー同士のエキシビションマッチや、チーム対抗リレーなどいろんなコンテンツがあって、交通費と宿も提供してもらえてすごい贅沢。
集合写真を撮る際にtouristの半径50cm内に接近するという実績解除(いま思えばおしりくらい触っておけばよかった)
Codeforcesを始める
ちょうどAtCoderに登録した頃はARC/AGCが割と高頻度で開催されていたのですが、間もなく月1回ペースとかになり、ratedが足りない!!!という気持ちに耐えられずCodeforcesとかいうのを始めました。
2017年12月11日にCodeforces Round 450 (Div. 2)に初参加。
2回目に出たEducational Codeforces Round 34 (Rated for Div. 2)では想定解が64ビット整数に収まらずhack祭りに見舞われ教育される。
2年目
このあたりの時期は、AtCoder Scoresの問題を配点が小さい方から順に埋めていってました。
ICPC 2018 国内予選
前年と同じくT君、H君とチームtojimboでICPC国内予選にリベンジします。
例のごとく1人1問ずつ解いたあとDに挑むも間に合わず…
またしても予選敗退でめちゃくちゃ悔しいという気持ちに
ICPC 2018 横浜大会
と思いきや、後に参加辞退したチームの補欠枠が降りてきてなんとICPC横浜大会に行けることに。2018年12月8日〜10日に横浜産貿ホール(?)みたいなとこでやります。
日本人同士での会話も含め会場内での公用語は英語。何言ってるかよくわからないのでとりあえずうなずいておきます。
初日は説明とリハーサルコンテストで本番のコンテストは2日目にお預け。早く本番やりたくてじれったい気持ちに。
本番は9時〜14時の5h。いつもとキー配列が違うのが最大の敵で、その影響で、タイピングと全く関係ない考察パートとかでもなぜか頭が混乱します。
3日目は東京をうろうろして、帰りは3人で高速バスで帰ったのですが、静電気恐怖症なので、バスのUSB端子(?)みたいなところからくる静電気に怯えてまともに眠れず、来年は一人で新幹線で帰ろうと心に決めました。
Twitterアカウント作成
競プロ界隈はtwitterでかなり情報共有とかされているので、2019年1月2日にtwitterアカウント「りーふ@競プロ」を作りました。
その結果、同学の後輩にあたる競プロerのs君、e君に認識してもらえます。
全国統一プログラミング王決定戦本戦
の懇親会でtwitterで事前に連絡を取っていたs君、e君と初めてエンカ!いつも同じ大学に通ってるのになぜか東京で初遭遇。
翌日が卒論の提出日でしたが、元から締め切りが1日早かったことにするテクを使ったので問題ありませんでした。
3年目
その後、僕の研究室にe君とその友人のn君が入ってきてくれました!!
これまで1人で競プロしてきたので、学内で共有できる仲間が増えてこの年あたりからモチベがかなり上がっていきました。
一緒にクリスマスコンに参加したりたこ焼きを焼きながらバチャをする謎の遊びをしました。
Xmasコン情報です pic.twitter.com/0FrB4c3I4D
— りーふ@競プロ (@leaf_1415) December 24, 2019
誰がどうみてもたこ焼き pic.twitter.com/MvkJmCLEnM
— りーふ@競プロ (@leaf_1415) February 14, 2020
精進としてはAtCoder Problemsを片っ端から埋めていったり、Recommendationの問題を解いていきました。
ICPC2019国内予選通過
2019年7月12日 ICPC2019国内予選があったのですが、残念ながら学会発表が被っており、ボスには一人でフランスに行ってもらいました。
例年通りにT君、H君とチームtojimboで参加。
参加資格上この年が最後のチャンスで、結局4完の壁が破れなかった点は悔しかったのですが、3完早解きで今回は順当に予選通過!!
ICPC2019 横浜大会
会場着 pic.twitter.com/9p5Rpb45DN
— りーふ@競プロ (@leaf_1415) November 16, 2019
4完24位でした!!
入橙
2020年1月11日入橙!!!
4年目
2020年の4月から学科に競プロerのi君が入ってきてくれて弊学の競プロコミュニティのメンバーが1人増えました!図書館でi君っぽい人に話しかけたらi君でした!!
クリスマスコンではそのとき始めて遭遇した同学科のc君と、s君、i君との4人で参加して撃沈
Xmasコン情報⚠️ pic.twitter.com/eTTH7T7NSP
— りーふ@競プロ (@leaf_1415) December 24, 2021
こ。この頃に、JOI埋めに手を出してみましたが、なんか問題傾向がしんどくて続きませんでした。友人(競プロerではない)からやっぱそういうのは実戦形式でやらんと〜と言われてたしかにとなったので、2020年11月〜2021年7月にかけてこどふぉのばちゃを毎日1バチャずつくらいやりました。上達した実感とかはよくわからなかったんですが、現象としてはレートが上がっていった気がします。
Yukicoderで単独writerのコンテスト
天才コンを作りました
5年目
ABCのwriterになれるチャンス
2021年3月20日、chokudaiさんがtwitterでABCのwriterやりたい人を募集していたのですかさずDM!
こんな感じの内容ですがどうでしょう?!と説明をもらいましたが、ABCには直接writerをしてない回でも参加出来なくなるというのにちょっと尻込みしてしまい、やります!と返信するのが1日後になった結果、既に枠が埋まってしまいました
(多分こいつのせい↓↓)
ICPC2021 国内予選
2021年11月5日 ICPC2021国内予選は学生コーチとして、このとき初めて会うm君と、s君、c君のチームを応援。
そして弊学初の4完を達成して予選通過してくれました!!
コロナの影響でオンサイトにはならず横浜に行けなかったのだけが惜しかった
ABC writerデビュー
もう1度声をかけてもらう機会があったので今度こそwriterとしてすぐに名乗りを上げました。その後、
「原案作りたいです!」
「わかりました試しに送ってみてください」
(原案いろいろ送る)
「…どうしても原案やりたいですか…??」
「そこをなんとか〜(泣)」
そしてついに、
leaf1415さんってもしかしてあのイケメンで聖人君子なことで有名なあのleaf1415さん?! pic.twitter.com/FKUXIxomqO
— りーふ@競プロ (@leaf_1415) July 16, 2021
その後ABCに賞金付きコンテストが増え始める
許せね〜
その後、同学の競プロerで以前からtwitter上で相互に認識していたt君ともエンカ!!
福井大学首脳会議を行いました😌 pic.twitter.com/WkGGKdP1Iz
— りーふ@競プロ (@leaf_1415) September 6, 2021
6年目
ぼくもえーあーるちーのらいたーやりたいでちゅ〜〜〜〜〜〜!!!!!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) April 23, 2022
ぼくもえーあーるちーのらいたーやりたいでちゅ2~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) May 14, 2022
ぼくもえーあーるちーのらいたーやりたいでちゅ3~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) May 28, 2022
ぼくもえーあーるちーのらいたーやりたいでちゅ4~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) June 18, 2022
ぼくもえーあーるちーのらいたーやりたいでちゅ5~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) July 29, 2022
ぼくもえーあーるちーのらいたーやりたいでちゅ6~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— 物理好き (@butsurizuki) July 29, 2022
ぼくもえーあーるちーのらいたーやりたいでちゅ7~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) August 19, 2022
ぼくもえーあーるちーのらいたーやりたいでちゅ8~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) September 3, 2022
ぼくもえーあーるちーのらいたーやりたいでちゅ9~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) September 10, 2022
ぼくもえーあーるちーのらいたーやりたいでちゅ10~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) October 8, 2022
えーあーるちーのらいたーでちゅ~~~~~~~!!!!!o(>ω< )o=o( >ω<)o pic.twitter.com/YlcNtauMQi
— りーふ@競プロ (@leaf_1415) October 15, 2022
7年目
CodeChefを始める
精進ペースが落ち気味になったので、以前から気になりつつもやってなかったCodeChefに参加する習慣をつけてみました。
AGCのwriterデビュー
ぼくもえーぢーちーのらいたーやりたいでちゅ~~~~~~~!!!!!o(>ω< )o=o( >ω<)o
— りーふ@競プロ (@leaf_1415) May 20, 2023
ARC用に投げていた原案が昇華してAGCに!
えーぢーちーのらいたーでちゅ~~~~~~~!!!!!o(>ω< )o=o( >ω<)o pic.twitter.com/BXtvP37vMy
— りーふ@競プロ (@leaf_1415) August 12, 2023
1700点とかもはや未知の領域だったので、これくらいの難易度感なのか〜と勉強になりました。それと報sy
レッドコーダーになる
そしてついに
6年ちょいかけてレッドコーダーになりました!!!!
今後
がんばります。
〇〇変換を使って畳みこみができる仕組み、完全に理解した
競技プログラミングでは、フーリエ変換やゼータ変換などを使って畳みこみの計算を行うことがしばしばありますが、こういった○○変換で畳みこみの計算ができる直感的なお気持ちを最近ようやくわかった気になったので、その勝手な解釈を文章にまとめました。
読みにくいところやいい加減なところがありますが、ご容赦ください。
畳みこみについて
集合 上の 項演算 があって、
与えられた つの 次元ベクトル から、 となる新たな 次元ベクトル を作る操作を、ここでは「畳みこみ」と呼び、 で表します。
演算 として、
などの場合が競プロにしばしば登場します。
ただし、 はbitwise-AND、 はbitwise-OR、 はbitwise-XORを表します。
の場合は、 を次の手順で計算できます。
演算 が他の定義の場合の例をいくつか挙げます。
この記事のテーマ
- 上に述べた畳みこみの計算方法はすべて、「〇〇変換を行ったものどうしの各点積に逆〇〇変換を行う」という形になってるけど、なんで全部そういう形になるんだろう?
- そもそも、なんで〇〇変換を使うと畳み込みの計算が出来るの?(数式で証明を見たら確かにそうなるのはわかるけど、もっと直感的なお気持ちが知りたい!)
↑これらは数ヶ月前の僕の疑問です。
畳みこみの別の捉え方
畳みこみは「半群代数上の積」と捉えることが出来ることが、こちらのmaspyさんの記事で触れられています。(わかりやすくてとても勉強になります)
[数学] 畳み込み入門:Dirichlet積とゼータ変換・メビウス変換 | maspyのHPmaspypy.com
以降の話に必要なところだけを大まかに述べると次の通りです。
集合 の各要素に対応する という 個の"モノ"を準備します。そして、 次元ベクトル を、 という 個の"モノ"の形式的な線形和で表すことを考えます。ここでは、この を の「線形和表現」と呼ぶことにします。
また、 と の積を と定めます。
このとき、 の線形和表現 と の線形和表現 の積 を計算すると、 の線形和表現が得られます。
例えば、 で の場合を考えます。
と を、それぞれ および のように線形和表現に変換し、それらの積を計算してみます。 と の積を で計算することに注意すると、
となり、これが の線形和表現と一致しています。 である事に注意してください。
一般に、 と をぞれぞれ線形和表現に変換し、その積を計算すると、
となり、 の線形和表現と一致します。
よって、 と から を求めるには下記の手順を行えばよいです。
- まず、とそれぞれ線形和表現に変換します。
- 次に、それらの積 を計算し、得られた積を とします。
- 線形和表現 から ベクトル を復元します。このとき、 となっています。
〇〇変換で畳み込みをするアイデア
〇〇変換で畳み込みをすることの主たるアイデアは、 を 本の複素ベクトル で代用することです。そして、 と の積 の計算を、
という各点積の計算に置き換えます。
下記の つの条件をともに満たすように、 本の 次元複素縦ベクトル を選びます。
- が任意の に対して成り立つ。
- は線形独立である。
これらの 本のベクトル を の代わりに用いると、 と から を求めるには次の手順を行えばよいです。
- まず、 の形にそれぞれ変換し、
- それらの各点積 を計算します。このとき、得られた積が の形で表せます。
- と変換すると、 が成り立ちます。
上記の手順1. の変換 は、
縦ベクトル を横に並べた行列 を用いれば、
と書けます。
上記の手順3. の変換 には であることを用いればよいです。 を線形独立になるように選んだので、 の逆行列は存在します。
結局、 と から を求めるには次の手順を行えばよいです。
- まず、 と に変換行列 を左から掛けて、 と を求めます。
- 次に、 と の各点積 を計算します。
- これに、変換行列 の逆行列 を掛けると、 が得られます。
実際、
となります。
これで、いろんな畳み込みが「〇〇変換を行ったものどうしの各点積に逆〇〇変換を行う」という形で計算できる仕組みがわかりました。納得してください。
畳みこみの具体例
結局、演算 の定義に応じて、変換行列 、すなわち 本のベクトル を、
- が任意の に対して成り立つ。
- は線形独立である。
という つの条件をともに満たすように選べれば、「〇〇変換を行ったものどうしの各点積に逆〇〇変換を行う」方法で畳みこみの計算ができることになります。
いくつかの具体例を以下で挙げます。
の場合
として、
をとることができます。(ただし、)
このとき、 は離散フーリエ変換になっています。
の場合
を次のように選ぶことができます。
- を、 のとき 、そうでないとき と定める。
このとき、 はゼータ変換になっています。
の場合
を次のように選ぶことができます。
- を、 のとき 、 のとき と定める。
変換 は累積和をとる操作になっています。
バグの記録
遭遇したバグの原因をここに列挙していきます。
増えてきたらそのうち整理します。
飽きました
・配列の長さが足りない
・与えられた N に対して、実際の数列の長さは 2N
・int型に収まらない入力をint型で受け取っている(以降の入力がおかしくなる)
・conitnue文で重要な更新処理をとばしている
・hとwが逆、xとyが逆
・非void型の関数が値を返していない(REになったりする)
・再帰が深すぎる(REになったりする)
・複数テストケースで、前のテストケースで使った変数を初期化してない
・sortの昇順と降順が間違っている
・配列の添え字の変数が違う(iとlを間違えたりする)
・>=と>を間違えてる
・浮動小数点数の計算誤差で落ちてる
・二分探索の上限値が足りてない