つちのこの日記

競プロと音ゲーがメインです。

キーエンス プログラミング コンテスト 2019 - F Paper Cutting(赤diff, 900点) 形式的冪級数解

問題リンク

atcoder.jp

 

問題概要

縦に $H$ 本、横に $W$ 本の線が引かれた長方形の紙がある。

一回の操作では、まだ選択してない線を一つ選択し、その線で紙を切る。その後紙の破片の個数をスコアに加算する。

操作をちょうど $K$ 回行う時、全ての操作方法に対するスコアの総和を求めよ。

制約
  • $1 \le H, W \le 10^7$
  • $1 \le K \le H + W$

解説

本解説では $[x^n]f(x)$ で形式的冪級数 $f$ の $n$ 次の項の係数を表すこととする。

$i$ 回目の操作で縦の線を選択した時のスコアの増加分の期待値を求めることを考える。これを $\mathcal{Ο}(1)$ で求められれば、この問題に $\mathcal{Ο}(K)$で答えられる。

考察を容易にするために、操作は 0_indexedで考える(つまり、操作は $0$ 回目から $K - 1$ 回目まで行う)。

$i$ 回目の操作の前に既に選択された縦線の個数を $j$ 本と固定してみる。この時、既に選択された横線の個数は $i - j$ 本である。

このような状態になっている確率は、 $ \frac{\displaystyle \binom {H-1}{j} \displaystyle \binom{W}{i-j}}{\displaystyle \binom{H+W-1}{i}} $ であり、この時得られるスコアは $ ( j + 2 )( i - j + 1) $ である。

ゆえに、 $i$ 回目の操作で縦の線を選択した時のスコアの増加分の期待値は以下の数式で表せる。 $$\displaystyle \sum_{j = 0} ^ i \left( \frac{\displaystyle \binom {H-1}{j} \displaystyle \binom{W}{i-j}}{\displaystyle \binom{H+W-1}{i}}( j + 2 )( i - j + 1) \right) \tag{*}$$ 

分母は $j$ に依存せず楽に計算できるので、後は分子を上手く扱う。

分子を $\binom {H-1}{j}(j + 2) $ と $\binom{W}{i-j}(i-j+1)$ に分けて考える。

一つ目については、 $$f(x) = \sum_{i = 0}^{\infty}\binom{H-1}{i} x^i$$ と置けば、 $$xf'(x) = \sum_{i = 0}^{\infty}{i \binom{H-1}{i} x^i}$$ であるから、

$$\begin{split} \binom {H-1}{j}(j + 2) & = [x^j] 2f(x) + xf'(x) \cr & = [x^j]( (H+1)x + 2)(1+x)^{H-2} \cr\end{split} $$ と表すことができる。

同様に、二つ目については $u := i-j$ と置けば

$$\begin{split} \binom{W}{i-j}(i-j+1) & = \binom{W}{u}(u+1)) \cr & = [x^u]( (W+1)x + 1)(1+x)^{W-1} \end{split} $$ と表せる。

ゆえに $${(*)} = \frac{1} {\binom{H+W-1}{i}}\displaystyle \sum_{j = 0} ^ i \left( [x^j] (H+1)x + 2)(1+x)^{H-2} × [x^{i-j}]( (W+1)x + 1)(1+x)^{W-1} \right)$$

これは畳み込みの形となっているので、求めるものは $$\frac{1} {\binom{H+W-1}{i}} [x^i] (1+x)^{H+W-3}( (H+1)x + 2) ( (W+1)x + 1) $$ と簡潔に表示できた。

$(1+x)^N$ の 任意の項の係数は、適切に階乗とその逆元を求めることで $\mathcal{Ο}(1)$ で求められるので、$i$ 回目の操作で縦の線を選択した時のスコアの増加分の期待値も $\mathcal{Ο}(1)$ で求められる。

縦線が選ばれる確率は $\frac{H}{H+W}$ 、横線が選ばれる確率は $\frac{W} {H+W}$ であるから、先ほどの期待値にこの確率を掛け合わせ、$i = 0$ から $K - 1$ まで足し合わせることでこの問題を $\mathcal{Ο}(K)$ で解くことができた。

実装の際には階乗と逆元の計算を適切に行うことや、負の二項係数にライブラリが対応していない場合 $H=W=1$ の時に正しい答えが返されないことに注意されたい。

ソースコード 

 

長いので折り畳み(includeやmodintは省略)
const int CombMAX = 20000010;
mint fac[CombMAX + 1], finv[CombMAX + 1], inv[CombMAX + 1];

struct Combinationinit {
    Combinationinit() {
        fac[0] = fac[1] = 1;
        finv[0] = finv[1] = 1;
        for(int i = 2; i <= CombMAX; i++) {
            fac[i] = fac[i - 1] * i;
        }
        finv[CombMAX] = fac[CombMAX].pow(MOD - 2);
        for(int i = CombMAX; --i;) {
            finv[i] = finv[i + 1] * (i + 1);
        }
    }
} Combinationinit_;

//nCk
mint COM(int n, int k) {
    if(n < 0) return COM(-n, k) * (k % 2 ? -1 : 1);
    if(n < k or k < 0) return 0;
    return fac[n] * finv[k] * finv[n - k];
}

mint COMinv(int n, int k) {
    if(n < 0) return COMinv(-n, k) * (k % 2 ? -1 : 1);
    if(n < k or n < 0 or k < 0) return 0;
    return finv[n] * fac[k] * fac[n - k];
}

//nPk
mint PER(int n, int k) {
    if(n < k or n < 0 or k < 0) return 0;
    return fac[n] * finv[n - k];
}

int h, w, k, i;
mint res;
int main() {
    scanf("%d%d%d", &h, &w, &k);

    for(i = 0; i < k; i++) {
        mint tres = COM(h + w - 3, i) * 2
                  + COM(h + w - 3, i - 1) * (h + 2 * w + 3)
                  + COM(h + w - 3, i - 2) * (h + 1) * (w + 1);
        mint yres = COM(h + w - 3, i) * 2
                  + COM(h + w - 3, i - 1) * (w + 2 * h + 3)
                  + COM(h + w - 3, i - 2) * (h + 1) * (w + 1);
        res += (tres * h + yres * w) * COMinv(h + w - 1, i);
    }

    cout << res * PER(h + w, k) / (h + w) << endl;

    return 0;
}

yukicoder contest 276 で Writer をやった話

前書き

yukicoder contest 276で単独Writerをやりました、nok0です。セットを投稿するのは初めてでしたが、楽しんで頂けていれば嬉しいです!

今日単独コンテストを開催できたのは、yukicoder及びyukiさん、testerを心良く引き受けてくださった皆さん、全問の難易度等をチェックしてくれたくまー(@kuma_program)くんのおかげです、本当にありがとうございます。

自己紹介と諸々

最近AtCoderで黄色になりました。競プロ歴はまだ1年もないのですが、折角競プロというコンテンツに割とどっぷり浸かってしまったので、創作もやりたくなり、セットを出させていただきました!これらの問題を作ったのは多分青の頃なので、レートにあまり関係なく、作問は楽しめると思います(多分)。

 問題ごとの解説及び講評(注:問題のネタバレを大いに含みます)

A.OR XOR

tester:zkou(@meander_uts1)くん

First AC:hitonanodeさん(01:44) (以下、FAの時間は(分:秒)で表記します。)

一問目なので、易しい考察で解けること、及びに典型要素が学べることを重視してこの問題を置きました。bit演算を扱う問題はbit毎に着目すると良いことが多いです。結局xorが0なことから、この問題は

Nの立っているbitそれぞれについてをA,B,Cのいずれか2つに割り振る。ただしA,B,Cが全て正という条件を満たすために、A,B,C全てに一つ以上bitを割り振らなくてはいけない。

という問題に言い換えられます。そうすると、構築可能な条件もわかりやすかったのではないでしょうか?

解説にも書きましたが、Nの一番下の立っているbitを N & (-N) で取り出せるということを使うと実装が簡潔です。余談ですが、初めて私がこのテクニックを知ったのはsnukeさんの解説放送(確かBITを実装する回)だったはずで、めちゃくちゃ感動した記憶があります。

講評:いい感じに1問目としての役割を果たしてくれました。思ってたよりWA率が高かったですが、多くの皆さんが解いてくれたようでよかったです。

B.Random Array Score

tester:zkou(@meander_uts1)くん

First AC:sugarrrさん(02:27)

数学問兼ギャグ問枠です。

最初は各要素がi回目に選ばれた時の、総和の増加分の期待値を求めて、それを足し合わせることで答えを求めようとしてましたが(それでも普通にできます)、よく考えると各操作で期待値が2倍になることがわかります。 操作が少し難しそうに見えて答えがすごいシンプルに表されるのが面白いと思って出題しました。

ちなみに、問題文中の期待値が有理数で表せるというところはひっかけで、単純に整数で表すことができます。

講評:難易度自体は割と予想通りのものになりました。ただ、数学要素が強い問題だったので、寒色コーダーの方でも苦戦する方も一定数いらっしゃったようです。

C.Sum of Inversions

tester:NOYA(@NOYA08096071)さん

First AC:tatyamさん(10:23)

簡単な典型枠です。真ん中に着目するといいことがある場合が多いってことだったり、転倒数は座圧してBITに載せることで計算できるといったことだったりは、高難易度だと当然のように要求される典型事項なので、もし知らなかった場合はこの問題を通して学んでいただければ嬉しいです。

講評:どちらかと言えば考察力よりも実装力、基礎的なデータ構造の使い方を問うつもりの問題でした。実装が重めでしたがかなり解かれていて、みなさんの競プロ力の高さを感じました。

D.Strange Graph Shortest Path

tester:zkou(@meander_uts1)くん

First AC:beetさん(02:21)

典型枠2(このセット、典型が多い気がしてきました)、コストがintに収まりきらない最小費用流のverifyにお使いください。解法ではなく設定から作ったのですが、よく見ると蟻本に乗っていました。蟻本は本当に情報の密度が濃いので、この問題が解けなかった方は今一度読み返すといいかもしれません。

もともと想定はdijkstraしてから経路復元し辺の長さを変更し、再度dijkstraだったのですが、冷静になると大嘘でした(これを落とすためのケースがkiller-01で、k-th-shortest-pathをk = 1からある程度のkまで回して最短になったものを採用するコードを落とすためのケースがkiller-02です)。killer-02はtesterさんに考えてもらったので、感謝です。

ところでこの問題、c_i > d_i でも解けるんでしょうか?何かご存知の方いれば教えてくださると嬉しいです。

講評:中度典型枠でした。知っている方は爆速で通した(beetさんは早すぎて本当にびっくりました)一方、知らなかったり思いつかずDijkstraの嘘解法に走ってしまい、ペナを量産している方も見受けられました。概ね想定通りの難易度でした。

E.Random Tree Score

tester:まつかわ(@tpyneriver)さん

First AC:hos.lyricさん(07:43)

グラフ枠かつ冪級数を用いた数え上げ枠。次数の積という条件を扱いやすくするために、次数を固定して考えてみると解説の式が実験なりなんなりで出てくるはずです。(Cayleyの公式をこの補題から証明したことがある人なら秒だったかもしれません。)そこにさえ辿り着けば、単純な冪級数の累乗で答えが表示できます。最初は Ο(NlogN) 想定でしたが、非本質で落とすのも違う気がするのと、logの区別は難しいので、Ο(Nlog^2N)でも余裕で通る制約にしました。 

まつかわさんのtester解は、全然違うことやってます、すごいです。めちゃくちゃいい感じのpdf解説を書いていただいたので、そちらも合わせてご覧ください。

講評:やや難しめの数え上げ問題でした。割と非想定で通されている気がするので、コードをみて勉強した後に、解説及びここのブログに追記します。難易度は想定よりやや易しめだったでしょうか。

F.Inconvenient Kingdom

tester:hamamu(@hamamu_kyopro)さん

First AC:maroon_kuriさん(16:26)

ボス問枠、行列木定理を用いた数え上げを線形代数で高速化する問題。もともとはもっと簡単な問題でしたが、hamamuさんからの数々の助言のおかげでボス枠になりました。hamamuさんには問題文の日本語直してもらったりテストケースについて助言を頂いたり愚直解をチェックしていただいたり、、本当に頭が上がりません、めちゃくちゃお世話になりました。

この問題は、行列木定理に感動して作りました。全域木の個数が多項式時間で数え上げられるの、本当にすごくないですか?? 高速化の方法も割とシンプルでかなりお気に入りです。連結成分が2個以上の場合はちょっと場合分けがめんどいのですが、そこは頑張りましょう。

講評:思ってた以上に通されました。赤コーダーだったり本当に強い方々との力の差を痛感しました。hitonanodeさんの解が5msで、本当に脳内が???です、どうやってるんでしょう?

問題の準備にあたって

これ、めちゃくちゃ大変でした。そもそも作問って

原案の準備→解説の準備→問題文の準備→テストケースの準備→確認

って感じでなかなかやることが多いです。特に大変なのが問題文の準備で、わかりやすい日本語書くのって、めちゃくちゃむずいんですよね。長い文章をまとめあげる自信がなかったので、今回のセットは極力ストーリーをカットしました。

テストケースの準備はめんどくさいんですが、今回はRimeを使うことでめちゃくちゃ楽になりました。詳しくはbeetさんのブログをご覧ください。(とてもわかりやすくまとまっています。

後書き

作問はなかなか大変ですが、めちゃくちゃ楽しいので、是非皆さんもやりましょう!ちょっと前に作問でかなりやらかしてしまったのですが(本当にごめんなさい。。)、今日は無事に終わることができて安心しました!(しかもclar0を達成しました!!)本当にありがとうございました!

 

bit

ICPC2020 国内予選 参加記

昨日はICPC2020国内予選に参加しました。チームは毎度おなじみのSPJ(クマー、zkou、私)です。

本番の記録

  • 16:30〜

あれ?サイトに繋がりません。めちゃくちゃ焦ります。電話をしても繋がりません。なんか10分ぐらいしたら急に治りました。

  • 16:40〜

打ち合わせの通りに私がA、zkouがBを通します。クマーがCで苦戦しているので見ていくと、3乗根っぽいのはわかりますが解けません。(ここ戦犯ポイント1) めちゃくちゃみんなで高速化を考えてると、愚直解の実行が終わっています。ここまでで1時間くらい使ったのが結果的にはかなり痛かったね、、、

  • 17:40〜

DとEを並列に読みます。Dは構文解析パートは易しそうで、その後の解法について制約等からbitDPとかを考えるんですけど、これが良くなかったです。(戦犯ポイント2) 答え決め打って頑張るとかまでは思いついていたので、どうして順序を割り振ってbit全探索が出てこなかったのか、、、 結果的にDを通していれば余裕で予選通過だったので非常に悔やまれます。

Eは最初木DP?とか思うんですけど、全然木じゃなかったです笑(くまーにおこられました) 

  • 18:30〜

EがbitDPで高速ゼータ変換してうんちゃらするとかいう方針をzkouが思いつきます。(天才) 私は高速ゼータ変換良くわかっていないので(これは良くない)、一人でDを考えていました。

Dがよくわからないので、Fを見にいくと、これは部分永続Union-Findで勝てそうな問題に見えます。 辺の長さが小さい順からUFの辺を削除していって(これは部分永続Union-Findで簡単にできます(逆から辺を貼ればいいので))、最大じゃなくなった頂点集合を消していき、最終的に頂点集合のサイズが1となったときに残っている頂点が答えっぽいことに気付きます。これはどう見てもΟ(NMlogN)くらいかかりそうなんですけど、ちょっと高速化すればここまでにはならなさそう?と思ってコードを書き、実装すると5分くらいでデータセット1が終わります。

ノリノリで提出すると、WAと出てイライラします。入力と出力をじーっと比較すると、なんと1行まるまる飛んでいます。(N,M)=(1,0)のコーナーケースが入っていたそうです(ひどい) ここを直してFをACしました。

  • 19:00〜

くまーとzkouがEを頑張って書いているのですが、サンプルすら合いません。デバッグを応援しながらDを考えるのですが、全然解けません。デバッグを応援していると、終了直前でなんとかEが通り、そのまま終了。

結果は23位で大学内8位、予選敗退でした。

f:id:tsuchinok:20201107102445p:plain

感想

初めての参加ということもあり、緊張しましたがコンテスト自体は非常に楽しかったです。結果も、黄黄青の3人チームにしては上出来だと思いますが、Dが通せなかったのがとても悔しいです。

来年はもっと強くなってリベンジしたい、そう思いました。

 

WUPC4thに参加しました。

初めてのチーム戦でしたが、とても楽しかったです!運営の皆さん、及びにチームメイトに感謝です。

 

チームメイト

クマー : 同学年の強い青コーダーです。(すごい)

zkou : 同学年の強い青コーダーです。(すごい2)

: 普通の青コーダーです。

 

今日チームでACできた問題について解いた順番に軽くコメントします。

 

A : 2が含まれる時だけ気をつけます。流石にすぐに実装できました。(2分)

B : zkou君と割となやみました。a[i]とa[i+1]についてb[i] = a[i + 1], b[i + 1] = -a[i]とし、奇数の時だけ調整するという方針でやったのですが、もっといい方針がありましたね、、思いつきませんでした。(13分)

C : 問題を色々見て回ってから、簡単そうなCにいきました。コドフォでエスパー力とギャグセンスを鍛えていたので、すぐにわかりました。良かったです。(25分)

M : 問題文をみてすぐに全方位木DPなことはわかったのですが、実装の順番的に後回しになっちゃいました。すぐに書けることは割と明らかだったので、途中で実装順を変えた方がよかった気がします、反省です。(1時間2分)

なんとAからMまで実は全部私が実装してたみたいですね、びっくり、、 

J : SCCしてからどうするかわかんないよ〜っていってたらクマーが解いてくれました、凄い。(1時間19分)

E : この問題はzkou君がずっと考えてて、最後の実装だけ私が手伝ってACしました。まだ解法がよくわかってなくて、考えたいです。(2時間0分、1ペナ)

G : クマーとずっと悩んでて、私はΟ(N ^ 3)を投げようとしてクマーに止められてました(おい) でもコンテスト後に実際それで通してる人もいて、うーんになりました。zkouがすぐに閃いてくれて、実装を私がしてACしました(実装が下手で1ペナ出したの、謝罪、、) (2時間27分、3ペナ)

I : 私が他の問題考えてる間に、二人で解いてくれたみたいです。まだよくわからないけど、対角線付近しか絡まないギャグ問題っぽい?(3時間13分)

D : これはむずかったけど、みんなで考えて無事AC、diの積にmod N 上での逆元が存在すること気づかずにう〜〜んってなってました。(4時間4分、2ペナ)

K : 私とzkouで一生悩んでたのですが、クマーが点対称使うんじゃない?って言ってくれたおかげですぐに細部まで詰められて、AC。クマーに感謝です、、(4時間39分)

 

結果

11完で、全体では22位でした!初めてのチーム戦にしてはわりと上出来だった気がします。 (チームメイトが強すぎた、)

 

総括

初めてのチーム大会でしたが、とても面白かったです!コンテスト中の分担などの立ち回り、まだまだ詰められる部分ばかりだと思うので、これから頑張っていきたいですね〜

AtCoderで青色になりました

こんにちは!つちのこです。折角AtCoderで青色になったので、色変記事を書きました(記録になるので) 色変記事の自己紹介や精進方法は本当に自己満足に近いと思いますが(そこらへんは十人十色なので)、身に付けたアルゴリズムやデータ構造等は青を目指す方にとって参考になると思うので、是非読んでくださると嬉しいです!

1.恒例の?自己紹介タイム

といっても特に書くことないんですよね、スペックとしては始めた時点でプログラミング完全未履修、数学は高校数学までは少しだけわかるくらいの感じでした。

折角なので、競プロを始めたきっかけについてでも書いておきます。大学受験期に競プロの存在を知って、単純にゲームとして面白そう!と思ったのがきっかけです。全くプログラミングはできない一からのスタートでしたが、APG4bのお陰でc++の書き方を学んでいき、どんどんハマっちゃいました。 ちょうど初めて4ヶ月と少しで最初の目標であった青コーダーにまでなれたのでよかったです。

 

2.身に付けたアルゴリズムやデータ構造

昔緑コーダーになった記事を出したんですが、それから沢山増えちゃいました。今使えるのはここらへんです。

  • DP、桁DP、bitDP(やや怪しい)
  • 最短路(ダイクストラ、ワーシャルフロイド、ベルマンフォード)
  • 最小全域木(クラスカル、プリム)
  • union-find
  • BIT、抽象化再帰セグ木
  • Mod演算(modintクラスを作りました)
  • ローリングハッシュ 
  • LCA
  • トポロジカルソート

あれ、実は全然ないですね、、、思い出したらその都度追記していきます(ごめんなさい)もしこれは知ってるでしょ、とか青コーダーならこれは最低限使えた方がいいよ!っていうのがあれば是非教えてください。

それぞれについて一言コメントも書いちゃいます。

まずDPですが、青コーダーを目指すならある程度出来た方がいいです。EDPCがかなり良い教材なのでおすすめです。

最短路は時々使います。そこまで難しくも無いので早めに使えるようになると良いかも?

最小全域木クラスカルでもプリムでも基本は良いですが、クラスカルの方がわかりやすい気がしました。

union-findはまあご存知の通りですね。構造体の中でもかなり作るのが平易なので、緑くらいになったら自作してみるといいかもです。

BIT、セグ木はAtCoderのコンテスト中にはほぼ使ったことがないですが、かなり便利なので持っておくと便利です。セグ木は非再帰の方が早いらしいのでこんど作り直したい、、

Modintはあると実装での事故が減り、簡潔にコードを書けるようになります。メリットがかなり大きいので勉強する価値はありそうです。

ロリハは使うと非想定だけど解ける問題がそこそこあるので、凄い子です。ハッシュの衝突には注意です!

LCAは実は使ったことが無いので何も言えません、、

トポロジカルソートはコドフォで一回使ったくらいですかね、割とわかりやすいので水くらいになったら覚えても良いかもです。

3.精進でやったこと

 AtCoder上で900問くらい解いたみたいです。緑になった時が500ACだったので、およそ1.8倍くらいですね。私はそこそこ解説ACに頼っちゃうタイプなので、多分2割くらいは解説ACしています(もちろん、時間をあけて自分の力でACはしています)。

これはいろんな人が言ってることなんですけど、精進や問題を解くのにはいろんな種類があって、例えば低難易度を早く解く練習をすると、コンテストでめちゃくちゃやらかして3完茶パフォだった。。。みたいな事故を減らすことができます。逆に高難易度にじっくり取り組む訓練をすると、時々難しい問題が解けて高いパフォが出たりします。あとは、例えばめちゃくちゃ昔のABC-Dなどは典型の塊なので、割とすぐに解説を見ちゃっても典型力を身に着けることができます。精進も惰性で続けるんじゃなくて、何を目的に精進をやっているのかその都度明確に考えながら行うのが、実力向上のためには非常に大切な気がしています。

ところで、最近はCodeforcesのバーチャルコンテスト機能を割と良く使っているのですが、フォロワーさんと競えたり初見の問題に沢山取り組むことができるので、力をつけるにはかなり有用な気がしています。今後もバチャは精進に取り入れていきたいなーって思ってます。

 4.終わりに

いつもフォロワーさんには色々と教えていただいたりバチャ並走していただいたり大変お世話になっています。年内黄コーダー目指して頑張る予定なので、何卒今後もよろしくお願いします!! 

Topcoderで暖色コーダー(黄色)になりました!!!

f:id:tsuchinok:20200726123609p:plain

 

こんにちは、昨日のコンテストが駄目駄目で悲しんでいるつちのこです。

 

黄色コーダーになるまでにやったこと

・div2に1回参加しました。

・結果を見たらなぜか自分の名前が黄色になってました(!??)

 

はやくAtCoderのBeginner卒業してコドフォも薄橙になりたいです。

おしまい。

 

入緑しました!!

こんにちは、つちのこと申します。AtCoderを初めて1ヶ月と少し、やっと緑レートになることができました!

f:id:tsuchinok:20200505133655p:plain

 

折角なのでこれまでに取り組んだことをメモしていきます。

 

1.まず自己紹介

 私は18歳の大学一年生で、一応理系、専攻は物理系な予定(なお進振り)で、情報系に進むつもりは今のところ特にないです。趣味としては競プロやピアノ、チェスや音ゲー等を軽くやっています。

プログラミングの経験は、小学生の頃Scratch(猫のあれです)を少し触ったり、中学生でBasicを本当に軽く触ったくらいなので今年の3月までほぼ0でした。また、プログラミングの素養がめっちゃありそうな、いわゆる数強でもありません(二次試験の数学2/3くらいしか取れてないですし、、) そういう人でも精進すれば1ヶ月ちょいで緑まで行けるんだよーっていうのが伝わって、みんな競プロ始めてくれると嬉しいです!(競プロはとても楽しいので)

 

2.これまでにやったこと

 まず、競プロを始める際使用言語で悩んだのですが、一番使用人数が多く解説が豊富にあり、高速なc++にしました。特にこだわりがない場合c++にしてみるのをお勧めします。

 その後はAtCoderさんのAPG4bを3章の途中まで読んでc++の基礎を勉強しました 。多分そこまで読み終わったのは3/29くらいです。APG4bはかなりわかりやすくとてもお勧めですが、一部内容が難しかったり章末問題がとても難しかったりするので、そういうところは飛ばしちゃって後で戻って来ればいいと思います。(私もめちゃくちゃ飛ばしました) 

 そこからはひたすらにAtCoder Problemsというサイトを使ってABCの過去問を埋めてきました。問題を考えて解いてみて、もしわからなかったら解説(Editorial.pdfだったりけんちょんさんのブログだったり)をみて勉強しての繰り返しです。で、これまでどんくらい問題を解いたかというと

f:id:tsuchinok:20200505131631p:plain

現時点で504ACらしいです、思ってたよりやっていましたね。ペースについては以下の画像の通りです。モチベの変動が激しいので、モチベが高い日は沢山解いてますが低い日は全然やってません、まあ趣味でやっているのでこんな感じでいいと思ってます。

f:id:tsuchinok:20200505131755p:plain

 解いた問題の内訳は以下の通りです、正直虚無埋め(ABC-AとかBとか)はそこまで実力に寄与するものではないはずなのでやってもやらなくてもいいと思います。

f:id:tsuchinok:20200505132106p:plain

 

 

3.現時点で使えるアルゴリズム、データ構造について

 今私が使えるアルゴリズムやデータ構造ですが、以下のものくらいだと思います。

・(優先度付き)キュー、スタック、連想配列

・二分探索

・貪欲法

・累積和、いもす法

・簡単なDFS,BFS

・二項定理(MOD付き)

・簡単なDP、桁DP

・簡単なグラフ(正直よくわかってないです)

 

最近のABCでは、頻出のアルゴリズムやデータ構造を知らなくても思考力で解ける問題(ABC165-D,E,ABC166-D,E,F等)が多い気がするので、正直緑まではそこまでアルゴリズムやデータ構造の知識が無くても行けると思います。それ以上は厳しそうなので勉強しないとまずいですけど、、

 

4.今後の目標

 早く入水して寒色コーダーになりたいです!

 

以上です、読んで頂きありがとうございました!周りの競プロerさん方からいつも刺激を貰っているので、早く追いつけるように精進頑張りたいです!

もしよければ下のスターを押してくださるととても嬉しいです!