レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【上級編：目指せレッドコーダー！】

# 0. はじめに
* [レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【初級編：競プロを始めよう！】](https://qiita.com/e869120/items/f1c6f98364d1443148b3)
* [レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編：目指せ水色コーダー！】](https://qiita.com/e869120/items/eb50fdaece12be418faa)

からの続きです！

## 上級編から読む方へ
近年、[AtCoder](https://atcoder.jp/) を中心とした競技プログラミング（競プロ）の存在感が日に日に高まってきています。近年では、[AtCoderJobs](https://jobs.atcoder.jp/) という AtCoder での実力に応じて求人に応募できるサービスや、[アルゴリズム実技検定](https://past.atcoder.jp/)という名の検定サービスも現れてきています。

そんな中、**「競プロでどうやって上達すれば良いのかわからない」**と思い悩んでいる方は多いと思います。その悩みも、実力帯ごとに異なり、

* 最初に何をやれば良いのか悩んでいる競プロ未経験者もいる
* 競プロ成績上位に食い込むためには何をやれば良いのか悩んでいる人もいる
* 部活や社内などで、どういう競プロの教え方をすれば良いのか悩んでいる人もいる

と思います。そこで本記事では、**競技プログラミングで上達するためにはどういうことを学べば良いのか、どういう練習をすれば良いのかのガイドラインをレベル別に示し、上達に役立ててもらう**ことを最大の目標としております。

## 目次
#### [初級編](https://qiita.com/e869120/items/f1c6f98364d1443148b3)
|章  |タイトル  |備考  |
|---|---|---|
|0.  |[はじめに](https://qiita.com/e869120/items/f1c6f98364d1443148b3#0-はじめに)  |  |
|1-1.  |[競プロとは何か](https://qiita.com/e869120/items/f1c6f98364d1443148b3#1-1-競プロとは何か)  |ここからサポートしていきます  |
|1-2.  |[競プロの 6 つの面白さ](https://qiita.com/e869120/items/f1c6f98364d1443148b3#1-2-競プロの-6-つの面白さ)  |「競プロって、面白い」を伝えていきます  |
|1-3.  |[早速競プロを始めてみよう](https://qiita.com/e869120/items/f1c6f98364d1443148b3#1-3-早速競プロを始めてみよう)  |  |
|1-4.  |[AtCoder のレーティングとは](https://qiita.com/e869120/items/f1c6f98364d1443148b3#1-4-競プロをやる前に-atcoder-のレーティングとは)  |  |
|1-5.  |[「茶色コーダー」で要求される 4 つのこと](https://qiita.com/e869120/items/f1c6f98364d1443148b3#1-5-茶色コーダーで要求される-4-つのこと)  |  |
|1-6.  |[「茶色コーダー」になるためのガイドライン](https://qiita.com/e869120/items/f1c6f98364d1443148b3#1-6-茶色コーダーになるためのガイドライン)  |初級編のメインです  |
|1-7.  |[Tips： AtCoder の過去問を解ける便利なサイト](https://qiita.com/e869120/items/f1c6f98364d1443148b3#1-7-tips-atcoder-の過去問を解ける便利なサイト)  |  |
|1-8.  |[おまけ：競プロにおける C++ のすすめ](https://qiita.com/e869120/items/f1c6f98364d1443148b3#1-8-おまけ競プロにおける-c-のすすめ)  |  |

#### [中級編](https://qiita.com/e869120/items/eb50fdaece12be418faa)
|章  |タイトル  |備考  |
|---|---|---|
|2-1.  |[「水色コーダー」で要求される 4 つのこと](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-1-水色コーダーで要求される-4-つのこと)  |  |
|2-2.  |[「水色コーダー」になるためのガイドライン](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-2-水色コーダーになるためのガイドライン)  |中級編のメインです  |
|2-3.  |[分野別　初中級者が解くべき過去問精選 100 問](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-分野別初中級者が解くべき過去問精選-100-問)  |この 100 問解けば実力上がると思います  |
|2-4.  |[「水色コーダー」を目指す人のための Tips 5 個](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-4-水色コーダーを目指す人のための-tips-5-個)  |  |

#### 上級編
|章  |タイトル  |備考  |
|---|---|---|
|3-1.  |[「黄色コーダー」で要求される 6 つのこと](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-1-黄色コーダーで要求される-6-つのこと)  |  |
|3-2.  |[「黄色コーダー」になるためのガイドライン](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-黄色コーダーになるためのガイドライン)  |上級編のメインです  |
|3-3.  |[分野別　上級者が解くべき過去問精選 100 + 50 問](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-3-分野別上級者が解くべき過去問精選-100--50-問)  |この 150 問で実力上がります  |
|3-4.  |[「競プロ典型 90 問」のすすめ](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-4-%E7%AB%B6%E3%83%97%E3%83%AD%E5%85%B8%E5%9E%8B-90-%E5%95%8F%E3%81%AE%E3%81%99%E3%81%99%E3%82%812021712-%E8%BF%BD%E8%A8%98)  |新たに誕生した教材です  |
|3-5.  |[「黄色コーダー」を目指す人のための Tips 4 個](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-5-黄色コーダーを目指す人のための-tips-4-個)  |  |
|4.  |[「橙色コーダー」になるためには何をすれば良いか？](https://qiita.com/e869120/items/acba3dd8649d913102b5#4-橙色コーダーになるためには何をすれば良いのか)  |橙色までサポートします  |
|5.  |[「橙色コーダー」の先　～ガチンコ競技としての競プロのはじまり～](https://qiita.com/e869120/items/acba3dd8649d913102b5#5-橙色コーダーの先ガチンコ競技としての競プロのはじまり)  |  |
|6.  |[おわりに](https://qiita.com/e869120/items/acba3dd8649d913102b5#6-おわりに)  |  |
<br />

# 3-0. 上級編で紹介すること
上級編では、AtCoder で<font color="#AAAA00">**黄色コーダー**</font>（レーティング <font color="AAAA00">**2000**</font>）、そして<font color="#FF7700">**橙色コーダー**</font>（レーティング <font color="#FF7700">**2400**</font>）まで上達する方法を記します。

なお、AtCoder のレーティングは以下の通りです。黄色コーダーだと**上位 2%**、橙色コーダーだと**上位 0.6%**くらいです。[^1]

|レーティング  |色  |相対的な位置  |絶対的な位置 |
|---|---|---|---|
|2800+  |<font color="#FF0000">**赤**</font>  |上位 0.2%  | |
|2400-2799  |<font color="#FF7700">**橙**</font>  |上位 0.6%  | |
|2000-2399  |<font color="#AAAA00">**黄**</font>  |上位 2%  |アルゴリズムの研究職・研究開発で重宝されるレベル |
|1600-1999  |<font color="#0000FF">**青**</font>  |上位 5%  |ほとんどのIT企業でアルゴリズム能力がカンストする |
|1200-1599  |<font color="#00AAAA">**水**</font>  |上位 10%  |半数以上のIT企業でアルゴリズム能力がカンストする |
|800-1199  |<font color="#007700">**緑**</font>  |上位 20%  |エンジニアとしてかなり優秀 |
|400-799  |<font color="#774400">**茶**</font>  |上位 35%  |学生なら優秀 |
|1-399 |<font color="#777777">**灰**</font>  |上位 100%  | |
<font color="red">(2020/08/03 相対的な位置を修正 (更新) しました)</font>
※ 絶対的な位置に関しては [AtCoder 社長・chokudai さんのブログ](http://chokudai.hatenablog.com/entry/2019/02/11/155904) がソースです。
![38.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/fb35b0ee-6968-2bae-c6c9-679b3c9717c0.png)
<br />

# 3-1. 「黄色コーダー」で要求される 6 つのこと
AtCoder で<font color="#AAAA00">**黄色コーダー**</font>、つまり<font color="#AAAA00">**レーティング 2000**</font> に到達するには、

* AtCoder Beginner Contest でほぼ確実に 5 問正解できる
* AtCoder Beginner Contest で確率 50% で全問（6 問）正解できる
* それほど難しくない問題（500 点以内）をかなり速く解くことができる
    * 問題毎の正解者数によるが、A 問題だと 1 分、B 問題だと 2 分、C 問題だと 5 分、D 問題だと 10 分、E 問題だと 20 分が目安。
    * 目安通りの時間で解けば、40 分以内で 5 問正解できる。
* AtCoder Grand Contest (AGC) などの数学的考察を要するコンテストでも、ある程度の戦績を残す
    * 例えば AGC の場合、2 問正解以上が望ましい

ことが要求されます。そのためには、以下の 6 つのことができれば良いと考えます。（もちろん、[水色コーダーで要求される 4 つのこと](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-1-%E6%B0%B4%E8%89%B2%E3%82%B3%E3%83%BC%E3%83%80%E3%83%BC%E3%81%A7%E8%A6%81%E6%B1%82%E3%81%95%E3%82%8C%E3%82%8B-4-%E3%81%A4%E3%81%AE%E3%81%93%E3%81%A8)は全てクリアしている必要があります。）

#### 条件 1
「[プログラミングコンテストチャレンジブック（蟻本）](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%96%E3%83%83%E3%82%AF-%E7%AC%AC2%E7%89%88-%EF%BD%9E%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E6%B4%BB%E7%94%A8%E5%8A%9B%E3%81%A8%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B%EF%BD%9E-%E7%A7%8B%E8%91%89%E6%8B%93%E5%93%89/dp/4839941068)」に載っている大半のアルゴリズムとデータ構造を理解する。具体的には、以下のアルゴリズム（計 23 個）とデータ構造（計 5 個）を理解する。

(i) [中級編 2-1. 節](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-1-%E6%B0%B4%E8%89%B2%E3%82%B3%E3%83%BC%E3%83%80%E3%83%BC%E3%81%A7%E8%A6%81%E6%B1%82%E3%81%95%E3%82%8C%E3%82%8B-4-%E3%81%A4%E3%81%AE%E3%81%93%E3%81%A8)に書かれている 12 個のアルゴリズムと 3 個のデータ構造。

| | | | |
|---|---|---|---|
|全探索 |二分探索 |深さ優先探索 |幅優先探索 |
|動的計画法 |ダイクストラ法 |ワーシャルフロイド法 |クラスカル法 |
|高速な素数判定法 |べき乗の高速な計算 |逆元の計算 |累積和・いもす法 |
|グラフ理論 |木 |Union-Find |

(ii) 中級編には書かれていないが蟻本には書かれている、11 個のアルゴリズム。

| | | | |
|---|---|---|---|
|座標圧縮 |半分全列挙 |行列累乗 |ダブリング |
|Grundy 数 |Rolling Hash |平方分割 |最大流 |
|最小カット |二部グラフ判定 |二部マッチング | |

(iii) 中級編には書かれていないが蟻本には書かれている 2 個のデータ構造。

| | |
|---|---|
|Binary Indexed Tree (BIT) |セグメント木（※遅延評価セグメント木を含む） |

#### 条件 2
条件 1 で紹介したアルゴリズム・データ構造をコンテスト中に引き出し、それらを使えるようになる。
つまり、本記事で紹介する「アルゴリズム」「データ構造」が完全に身につく、ということ。

#### 条件 3
ある程度の数学的考察ができるようになる。

※ AtCoder には、アルゴリズムが活用できるかどうかを問う問題だけでなく、数学的考察ができるかどうかを問う問題も出てきます。（[中級編 2-3. 節](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F) の問題 95 ～ 100 で述べた通りです。）特に、問題が難しくなるにつれ、この傾向が強まります。そのため、黄色コーダーになるためには、数学的考察を要する問題も十分に解ける必要があります。

#### 条件 4
25 行程度のプログラムであれば、ほぼバグらせずに書くことができる。
60 行程度のプログラムであっても、ある程度速く書くことができる。バグらせても、平均して 10 分以内でバグを解決できる。

※ 実際に、60 行程度のプログラムを、バグ取り含めて平均して 30 分以内で書けるようになれば、AtCoder Beginner Contest で全問正解 75 分以内が十分望めます。

#### 条件 5
タイピングがある程度高速にできる。経験則では、1 分間におよそ 350 タイプ数以上の速度があることが望ましい。

実際に、成績上位者の中にもタイピングが遅い（200 タイプ数など）人は一部いますが、特に AtCoder Beginner Contest を戦うにあたって、タイピングの速度はとても重要です。

例えば、[AtCoder Beginner Contest 148](https://atcoder.jp/contests/abc148) において、30 分で全完するのと 40 分で全完するのでは、パフォーマンスが **250 以上** 異なります。

#### 条件 6
AtCoder の過去問を目安として 1000 問以上解き、競プロの問題に完全に慣れる。

#### 補足
上の 6 つの条件を満たすようになれば、AtCoder Beginner Contest の E 問題までは安定して早解きできると思います。F 問題も、正解者数が 250 人を超える比較的簡単な問題であれば、正解することができると思います。

ちなみに、直近 15 回の AtCoder Beginner Contest (ABC141 ～ ABC155) において、F 問題の正解者数が 250 人を超えたのは 7 回です。そのように、全問正解を 3 - 5 割の確率で達成するのも十分可能です。

また 6 つの条件を満たすと数学的考察力も向上してくるので、AtCoder Grand Contest の問題も段々と解ける割合が増えてくると思います。

---

さて、それらができるようになるためには、どのような練習をすれば良いのでしょうか。

# 3-2. 「黄色コーダー」になるためのガイドライン
<font color="#AAAA00">**黄色コーダー**</font>に到達するためにやるべきことは、以下の 7 つだと思います。

* [ステップ 1: 11 個のアルゴリズムを新たにマスターする！](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-1-11-%E5%80%8B%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%82%92%E6%96%B0%E3%81%9F%E3%81%AB%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%99%E3%82%8B)
* [ステップ 2: 2 個のデータ構造を新たにマスターする！](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-2-2-%E5%80%8B%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%82%92%E6%96%B0%E3%81%9F%E3%81%AB%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%99%E3%82%8B)
* [ステップ 3: TopCoder SRM の問題を解いて数学的考察力をつける！](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-3-topcoder-srm-%E3%81%AE%E5%95%8F%E9%A1%8C%E3%82%92%E8%A7%A3%E3%81%84%E3%81%A6%E6%95%B0%E5%AD%A6%E7%9A%84%E8%80%83%E5%AF%9F%E5%8A%9B%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B)
* [ステップ 4: 日本情報オリンピック（JOI）の問題を解いて実装力をつける！](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-4-%E6%97%A5%E6%9C%AC%E6%83%85%E5%A0%B1%E3%82%AA%E3%83%AA%E3%83%B3%E3%83%94%E3%83%83%E3%82%AFjoi%E3%81%AE%E5%95%8F%E9%A1%8C%E3%82%92%E8%A7%A3%E3%81%84%E3%81%A6%E5%AE%9F%E8%A3%85%E5%8A%9B%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B)
* [ステップ 5: 過去問を解きまくる！](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-5-%E9%81%8E%E5%8E%BB%E5%95%8F%E3%82%92%E8%A7%A3%E3%81%8D%E3%81%BE%E3%81%8F%E3%82%8B)
* [ステップ 6: 「バーチャル参加」で早解き力をもっと鍛える！](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-6-%E3%83%90%E3%83%BC%E3%83%81%E3%83%A3%E3%83%AB%E5%8F%82%E5%8A%A0%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%81%A6%E6%97%A9%E8%A7%A3%E3%81%8D%E5%8A%9B%E3%82%92%E3%82%82%E3%81%A3%E3%81%A8%E9%8D%9B%E3%81%88%E3%82%8B)
* [ステップ 7: タイピングを練習して早解き力をさらに磨く！](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-7-%E3%82%BF%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%E3%82%92%E7%B7%B4%E7%BF%92%E3%81%97%E3%81%A6%E6%97%A9%E8%A7%A3%E3%81%8D%E5%8A%9B%E3%82%92%E3%81%95%E3%82%89%E3%81%AB%E7%A3%A8%E3%81%8F)

それぞれ、順番に説明していきたいと思います。

## 3-2-1. 11 個のアルゴリズムを新たにマスターする！
黄色コーダーになるためにマスターするべきアルゴリズムは、以下の 23 個です。

| | | | |
|---|---|---|---|
|全探索 |二分探索 |深さ優先探索 |幅優先探索 |
|動的計画法 |ダイクストラ法 |ワーシャルフロイド法 |クラスカル法 |
|高速な素数判定法 |べき乗の高速な計算 |逆元の計算 |累積和・いもす法 |
|座標圧縮 |半分全列挙 |行列累乗 |ダブリング |
|Grundy 数 |Rolling Hash |平方分割 |最大流 |
|最小カット |二部グラフ判定 |二部マッチング | |

そのうち、最初の 12 個（表の 1 ～ 3 行目）をマスターする方法は、[中級編 2-2-2. 節](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-2-2-12-%E5%80%8B%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%82%92%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%99%E3%82%8B)で解説がされていますので、こちらをご覧ください。本節では、残りの 11 個を理解できる記事たちを紹介したいと思います。

#### 座標圧縮
まとまった解説記事が見つからないので、こちらで簡潔に解説しておきます。

座標圧縮とは、とても大きい座標があって現実的に扱えないサイズである場合に、圧縮して計算量を抑えるというテクニックです。以下の画像のように、相対的な位置関係が崩れないように圧縮します。（一次元の場合でも、二次元の場合でも通用します。）
![37.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/5725d1f7-0c64-5d2e-48b4-56b94851fc1e.png)
実装などを含めた詳しい部分は、以下の記事に書かれています。

* [座標圧縮について勉強した (java)| バイトの競プロメモ](http://baitop.hatenadiary.jp/entry/2018/07/08/224742)
* [座標圧縮| 個人的な競プロメモ](https://scrapbox.io/pocala-kyopro/%E5%BA%A7%E6%A8%99%E5%9C%A7%E7%B8%AE)

#### 半分全列挙
$N$ 通りの全列挙を $O(\sqrt{N})$ 程度の計算回数で効率的に計算する手法です。以下の記事で解説されています。<font color="red">(2020/08/03 更新)</font>

* [たのしい探索アルゴリズムの世界【前編：全探索、bit全探索から半分全列挙まで】の 5 章](https://qiita.com/e869120/items/25cb52ba47be0fd418d6#5-%E3%81%AF%E3%82%84%E3%81%84%E6%8E%A2%E7%B4%A2%E6%B3%95%E5%8D%8A%E5%88%86%E5%85%A8%E5%88%97%E6%8C%99)

#### 行列累乗
行列の累乗を[繰り返し二乗法](http://satanic0258.hatenablog.com/entry/2016/04/29/004730)を利用して効率的に求めるテクニックです。フィボナッチ数の $10^{9}$ 番目の値を高速に求めたり、漸化式の $10^{9}$ 番目の値を高速に求めたりすることに使われます。以下の記事で解説されています。

* [競技プログラミングにおけるDPの考え方 ~繰り返し２乗法と行列累乗~](https://cinnamo-coder.hatenablog.com/entry/2019/05/24/172153)

#### ダブリング
「$N$ 個次の要素を知りたい」という状況で頻繁に使われるテクニックです。以下の記事で解説されています。

* [ダブリング| sataniC++](http://satanic0258.hatenablog.com/entry/2017/02/23/222647)
* [最小共通祖先 (LCA) 問題に見る、ダブリング](https://www.slideshare.net/satanic2/ss-72500089)

#### Grundy 数
競プロには、ゲーム理論の問題がよく出ます。ゲーム理論の問題を解くにあたって、「[Nim](https://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%A0)」というゲームに見ることができる「Grundy 数」は知っておくべき概念です。以下の記事で解説されています。

* [競プロにおけるNim、Grundy数とNimK](http://yang33-kassa.hatenablog.com/entry/2017/12/21/202812)

#### Rolling Hash
競プロでは、文字列に対するクエリに高速に答えるなどといった問題がよく出ます。文字列系の問題を解くにあたって、Rolling Hash は知っておくべきアルゴリズムです。以下の記事で解説されています。

* [ローリングハッシュと Suffix Array](https://www.slideshare.net/hcpc_hokudai/rolling-hash-60984153)　の 1 ～ 18 ページ

#### 平方分割
平方分割（バケット法）は、簡潔に書くと、長さ $N$ の列を $\sqrt{N}$ 個ごとに分けて考えるアルゴリズムです。以下の記事で解説されています。

* [プログラミングコンテストでのデータ構造](https://www.slideshare.net/iwiwi/ss-3578491)　の 19 ～ 32 ページ

#### 最大流（最大フロー）
最大流は、グラフ上の流れ（フロー）を扱うアルゴリズムの中では最も競プロで使われるものです。以下の記事で解説されています。

* [最大流 (max flow)](https://www.slideshare.net/hcpc_hokudai/max-flow)　の 1 ～ 34 ページ

#### 最小カット
フローで解ける競プロの問題の中には、最小カット問題に帰着することで解ける問題も多いです。最小カット問題に関する解説と正当性の証明は、以下の記事にまとまっています。

* [最大流 (max flow)](https://www.slideshare.net/hcpc_hokudai/max-flow) の 35 ～ 45 ページ

#### 二部グラフ判定
そもそも「二部グラフ」って何でしょう？　これは、グラフの各頂点を青と赤で塗るとき、「青の頂点同士を繋ぐ辺」「赤の頂点同士を繋ぐ辺」が存在しないように塗ることができるグラフのことです。

二部グラフは特殊な性質を持っているため、競プロで問題にされることが多いです。そのような問題を解くためにはまず、グラフが二部グラフかどうかを判定しなければなりません。その二部グラフ判定は、以下の記事で解説されています。

* [2 部グラフ判定問題](http://prd-xxx.hateblo.jp/entry/2017/10/13/004256)

#### 二部マッチング
二部グラフのマッチングは、輸送問題など実世界の問題を解くときによく使われるアルゴリズムです。もちろん、競プロで出題されることもあります。以下の記事で解説されています。

* [‪実世界で超頻出！二部マッチング (輸送問題、ネットワークフロー問題）の解法を総整理！‬](https://qiita.com/drken/items/e805e3f514acceb87602)
<br />

#### 補足
新たに学習したアルゴリズムを使って解ける問題は、

* [3-3. 節：分野別　上級者が解くべき過去問精選 100 + 50 問](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-3-%E5%88%86%E9%87%8E%E5%88%A5%E4%B8%8A%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100--50-%E5%95%8F)

に載っています！

## 3-2-2. 2 個のデータ構造を新たにマスターする！
前節で述べた通り、競技プログラミングにはアルゴリズムを学ぶことが大切です。一方、データ構造を学ぶことも大事です。

さて、<font color="#AAAA00">**黄色コーダー**</font> になるために必要なアルゴリズムは、以下の 2 つです。

* Binary Indexed Tree (BIT)
* セグメント木（RMQ だけでなく、遅延評価セグメント木などを含む）

それらのアルゴリズムが学習できる記事たちなどを紹介します。

#### Binary Indexed Tree (BIT)
競プロで頻出のデータ構造の一つです。解説は、以下の記事にまとまっています。

* [Binary Indexed Tree](https://www.slideshare.net/hcpc_hokudai/binary-indexed-tree)　の 1 ～ 20 ページ
* 21 ページ目以降も、競プロのどういう場面で BIT が使われるかが書いてあるので、読むといいと思います。

#### セグメント木
競プロで頻出のデータ構造の一つです。AtCoder ではそれほど多く見ないですが、[日本情報オリンピック](https://www.ioi-jp.org/)では、とても多くの問題がセグメント木を使って解けます。

基本的に、セグメント木は

* 単純なセグメント木（RMQ またはその亜種）
* 遅延評価セグメント木

の 2 つに分かれます。それぞれの解説は、以下の記事にまとまっています。

**典型１：RMQ を解くアルゴリズム**

* [Range Minimum Query (RMQ)](https://www.slideshare.net/hcpc_hokudai/rmq-47663507) の 1 ～ 23 ページ目
* 図を用いてわかりやすく解説されています。

**典型２：遅延セグメント木**

* [遅延評価セグメント木をソラで書きたいあなたに](http://tsutaj.hatenablog.com/entry/2017/03/30/224339)
* 「遅延評価セグメント木とは何なのか」という説明から、遅延評価セグメント木のアルゴリズム、そしてそれを使えばどんな問題が解けるのか、まで解説されています。

#### 補足
新たに学習したデータ構造を使って解ける問題は、

* [3-3. 節：分野別　上級者が解くべき過去問精選 100 + 50 問](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-3-%E5%88%86%E9%87%8E%E5%88%A5%E4%B8%8A%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100--50-%E5%95%8F)

に載っています！

## 3-2-3. TopCoder SRM の問題を解いて数学的考察力を鍛える！
前述のとおり、<font color="#AAAA00">**黄色コーダー**</font>になるためには、アルゴリズム活用能力だけでなく、数学的考察力も身につける必要があります。一方で、アルゴリズムを学習するだけでは数学的考察力は身につきません。果たして、どのような練習をしたら数学的考察力が身につくのでしょうか。

そこで、お勧めの練習方法は、

* [TopCoder](https://www.topcoder.com/) の SRM を解くこと

です。ちなみに、SRM とは Topcoder で開かれる競プロコンテストのことです。私が TopCoder を解くのをお勧めする理由は以下の 2 点です。

* TopCoder の問題は、全般的に数学的考察力が問われる問題の割合が大きい
* ただ数学的考察力が問われるだけではなく、解いた時の学びが多い問題の割合も大きい

そこで、どのようにして TopCoder の問題を解けばよいのでしょうか。

#### TopCoder に登録する方法
TopCoder の問題を解くには、アカウントを登録する必要があります。アカウントを登録する方法は以下の記事に書かれています。

* [TopCoderアカウント登録、SRM(Single Round Match)解説](https://pokutuna.hatenablog.com/entry/20080720/1216514672)

#### TopCoder で問題を解く方法
さて、アカウント登録が完了した人へ。TopCoder は AtCoder のように問題閲覧・提出方法が簡単ではないので、どのようにして問題を見るか、どのようにして提出するかわからない人が多いと思います。以下の記事に解説されていますので、是非お読みください。

* [Topcoderで練習問題にたどり着くのに一苦労した話。サイトの構成が複雑すぎる](http://www.blogtoranosuke.com/archives/11601108.html)

#### SRM Div1 Easy を埋めよう　～Div1 Easy Hunting 50問～
さて、数多くある SRM の問題の中から、何を解けばよいのでしょうか。水色コーダーや青色コーダーにとっては、**SRM Div1 Easy** の難易度を解くのが適切です。AtCoder 換算で 400 ～ 700 点相当の難易度の問題が多いです。

そこで、SRM Div1 Easy の中で数学的考察力が身につく教育的良問 50 問を紹介します。是非解いてみましょう。

* [SRM Div1 Easy Hunting 50問](https://docs.google.com/spreadsheets/d/1HpCzGy_FlOk7p0Ok6x_InM-l49luYau1MCCObtfknFA/edit#gid=1527555479)　by　@square1001 

## 3-2-4. 日本情報オリンピック（JOI）の問題を解いて実装力を鍛える！
前節では、<font color="#AAAA00">**黄色コーダー**</font>になるためには、数学的考察力が必要だと書きました。一方で、黄色コーダーになるために、実装力も必要だと思います。例えば、

* 50-70 行程度のプログラムを素早く書く
* 50-70 行程度の長めのプログラムでも、バグの発生する個数をできるだけ少なくする

などが要求されます。そこで、実装力を鍛えるために、解くべき最も適切な過去問は、

* [日本情報オリンピックの過去問](https://joi.goodbaton.com/)

です。日本情報オリンピックの問題は実装が重いものが多く、実装の練習になります。ちなみに、ものによっては 200 行以上の実装を要する問題もいくつかあります。

[https://joi.goodbaton.com/](https://joi.goodbaton.com/) に難易度別過去問リストが載っているので、是非解いてみてください。難易度は 1 ～ 12 の 12 段階に分かれているのですが、各実力帯ごとの解くべき難易度は、

|AtCoder レート |解くべき難易度帯 |
|---|---|
|水色コーダー |6 ～ 7 |
|青色コーダー |7 ～ 9 |
|黄色コーダー |8 ～ 10 |

といった感じです。
![26.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/52a31389-53a7-9471-1079-78b674caa9e0.png)

## 3-2-5. 過去問を解きまくる！
<font color="#AAAA00">**黄色コーダー**</font>になるためには、たくさんの過去問を解く必要があります。実際に、AtCoder の正解問題数と、黄色コーダーを達成できた割合は、以下のようになっています。<font color="red">(2019/12/09 時点の統計です)</font>[^2]

|正解問題数 |黄色コーダー達成割合 |
|---|---|
|500 - 599 問 |6.8% |
|600 - 799 問 |11.5% |
|800 - 999 問 |17.1% |
|1000 - 1199 問 |35.4% |
|1200 - 1499 問 |58.8% |
|1500 - 1999 問 |87.1% |
|2000 問以上 |100.0% |

そのため、[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/) などを使って、過去問を解きまくることが大切です。しかし、SRM や JOI の問題も含めて解いたり、アルゴリズムやデータ構造をしっかり理解できた人の方が、上達は速いと思います。

ですので、過去問を解くのは大切ですが、ただ過去問をがむしゃらに解くのではなく、3-2-1. 節から 3-2-4. 節までで述べたことを意識して過去問埋めをしましょう。

## 3-2-6. 「バーチャル参加」を活用して早解き力をもっと鍛える！
[中級編](https://qiita.com/e869120/items/eb50fdaece12be418faa)では、[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/) によるバーチャルコンテストのサービスを紹介しました。一方、2019 年 11 月、AtCoder 公式が、コンテストを仮想的にやることができるシステムを開発しました。

これが、**「バーチャル参加」**です。
![27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/95d2f06b-dbe5-5f8b-7f31-6f210af339cf.png)
バーチャル参加では、リアルタイムで「バーチャル順位表」が更新されるので、コンテストのような感覚で問題を解くことができます。（過去にバーチャル参加をやった人の中での順位が、バーチャル順位表に反映されます。）
![28.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/d153816c-d4bb-1c6a-8289-5e3e89d18a72.png)
さて、早解き力を鍛えるためには、以下のようにバーチャル参加を活用すると良いと思います。

* AtCoder Beginner Contest を 1 個選び、バーチャル参加をする。
* これは、昔の 4 問編成のコンテストでも、現在の 6 問編成のコンテストでも良い。
* できれば解いていない問題が多い方が良いが、直近 1 カ月以内に解いた問題が存在しない場合は、バーチャル参加するコンテストとして選べる。
* これを週に 2-3 回やる。（4 問編成だと 50 分、6 問編成だと 80-100 分で終わると思うので、大した負担ではない。）

もう一個有効な手段があって、これは**バーチャル参加中の自分を振り返る**という手段です。バーチャル参加後に、自分がコンテスト中にどのような動きをしたのか、そして実際にどこで時間を取られたのか（考察か、実装か、バグ取りか）原因を分析することで、上達は速くなると思います。しかし、いちいちバーチャル参加中に自分の挙動をメモすることはできません。そこで役立つのは、

* バーチャル参加中の、パソコンのスクリーンの動きをビデオで撮っておく

ということです。録画の方法については、例えば Windows 10 の場合

* [Windows10 の標準機能で画面録画の動画とキャプチャを撮る方法「スクリーンショット」](https://www.pasoble.jp/windows/10/screen-capture.html)
* [意外と簡単！Windows10でPC画面録画する方法2つ](https://multimedia.reneelab.jp/windows10-screen-recorder.html)

をお読みください。（@renee さん [コメント](https://qiita.com/e869120/items/acba3dd8649d913102b5#comment-9ef232abe16de266903d)を頂きありがとうございます。）

## 3-2-7. タイピングを練習して早解き力をさらに磨く！
競技プログラミングは、速度の勝負という面があります。特に、AtCoder Beginner Contest ではその面が大きいです。例えば、[AtCoder Beginner Contest 148](https://atcoder.jp/contests/abc148) の場合、

|タイム |パフォーマンス |
|---|---|
|30 分全完 |<font color="#FF7700">**2400**</font> |
|40 分全完 |<font color="#AAAA00">**2146**</font> |
|50 分全完 |<font color="#0000FF">**1971**</font> |
|60 分全完 |<font color="#0000FF">**1813**</font> |

となり、10 分でパフォーマンス 250 以上変わることもあります。その 10 分を削り出すために重要になってくるのが**タイピング速度**です。

タイピングは、オンラインゲーム感覚で練習することができます。そこで、便利なサイトをいくつか紹介します。

#### 1. 寿司打
* [Flash タイピング【寿司打 - SushiDA -】](http://typing.sakura.ne.jp/sushida/)
* 日本語のタイピングが練習できます。
* ランキングもあって、楽しいです。

#### 2. 10FastFingers
* [Typing Test English - 10FastFingers.com](https://10fastfingers.com/typing-test/english)
* 英語の基本単語 200 語のタイピングが練習できます。

#### 3. P検　タイピング
* [無料タイピング練習| P検-ICTプロフィシエンシー協会](https://www.pken.com/tool/typing.html)
* 日本語と英語が両方できます。
* 多くの種類の文章が出てくるので、タイピングの練習の効果が比較的大きいです。

---

以上 7 項目を、ガイドラインとして説明しました。
この 7 項目をしっかりやれば、<font color="#AAAA00">**黄色コーダー**</font>、つまり<font color="#AAAA00">**レーティング 2000**</font> を達成できる確率は十分に高いと考えられます。

そして、皆さんが黄色コーダーになる頃には、既にほとんどの会社でアルゴリズム構築能力がカンストしてしまうという、とんでもなく優秀な人材になっているのです。
<br />

# 3-3. 分野別　上級者が解くべき過去問精選 100 + 50 問
[3-2-5. 節](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-5-%E9%81%8E%E5%8E%BB%E5%95%8F%E3%82%92%E8%A7%A3%E3%81%8D%E3%81%BE%E3%81%8F%E3%82%8B)で、

> AtCoder の問題を 1500 問解けば黄色コーダーになれる人が 8 割以上

と書きました。しかし、「習得したアルゴリズムをどれくらい使えるようになったか」によって、上達速度が大きく変わってきます。そこで、「これを解いたら学習したアルゴリズムが使えるようになる！」という教育的良問を中心に、<font color="#00AAAA">**水色コーダー**</font>以上の競プロ中級者・上級者が解くべき過去問を**精選 150 問**、紹介したいと思います。

## 1 ～ 100 問目
最初の 100 問は、中級編で紹介した基本的なアルゴリズム・データ構造で解ける問題がほとんどです。

* [本記事 2-3. 節| 分野別　初中級者が解くべき過去問精選 100 問](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)

にまとめられています。確かに初中級者と書いてあるのですが、100 問中 40 問程度が<font color="#00AAAA">**水色コーダー**</font>・<font color="#0000FF">**青コーダー**</font>相応の難易度です。ですので、<font color="#AAAA00">**黄色コーダー**</font>を達成していないうちは、100 問全部解く勢いで埋めることをおすすめします。

## 101 ～ 150 問目
最後の 50 問は、上級編で初めて紹介したアルゴリズム・データ構造で解ける問題がほとんどです。分野別にまとめられていますので、アルゴリズムを完全にマスターするために役立ててください。

基本問題から応用問題まで幅広く取り上げています。応用問題の中には難問も含まれるので、**黄色コーダーを目指す人は 50 問中 35 問正解を目安に頑張ってください。**50 問全部解けたら、ほぼ確実に<font color="#AAAA00">**黄色コーダー**</font>レベルのアルゴリズム活用能力がついたといって良いでしょう。

#### 座標圧縮
**101**　[DSL_4_A - Union of Rectangles](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_4_A&lang=ja)　二次元座標圧縮の基本問題です。
**102**　[ABC 036 C - 座圧](https://atcoder.jp/contests/abc036/tasks/abc036_c)　「座標圧縮とは何なのか」を感じられる問題です。
**103**　[JOI 2013 予選 5 - 魚の生息範囲](https://atcoder.jp/contests/joi2013yo/tasks/joi2013yo_e)
**104**　[JOI 2008 本選 5 - ペンキの色](https://atcoder.jp/contests/joi2008ho/tasks/joi2008ho_e)

#### 半分全列挙
**105**　[DPL_4_B - Coin Combination Problem II](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_4_B&lang=ja)　基本問題です。
**106**　[AtCoder Beginner Contest 032 D - ナップザック問題　の 34 点の部分点](https://atcoder.jp/contests/abc032/tasks/abc032_d)
**107**　[CODE THANKS FESTIVAL 2017 G - Mixture Drug](https://atcoder.jp/contests/code-thanks-festival-2017-open/tasks/code_thanks_festival_2017_g)
**108**　[JOI 2015 予選 6 - 財宝](https://atcoder.jp/contests/joi2015yo/tasks/joi2015yo_f)　とあるデータ構造を使うので、やや難しいです。

※ 中級編で 23 問目として紹介した [JOI 2008 本選 3 - ダーツ](https://atcoder.jp/contests/joi2008ho/tasks/joi2008ho_c) も半分全列挙で簡単に解けます。

#### 行列累乗
**109**　[yukicoder No.526 - フィボナッチ数列の第N項をMで割った余りを求める](https://yukicoder.me/problems/no/526)　基本問題です。
**110**　[AtCoder Beginner Contest 009 D - 漸化式](https://atcoder.jp/contests/abc009/tasks/abc009_4)　チャレンジ問題です。$O(N^{3}logMlogA)$ が間に合わないので、TLE がちょっと厳しいです。

#### ダブリング（最長共通祖先 [LCA] を含む）
**111**　[GRL_5_C - LCA: Lowest Common Ancestor](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_C&lang=ja)　基本問題です。
**112**　[AtCoder Beginner Contest 014 D - 閉路](https://atcoder.jp/contests/abc014/tasks/abc014_4)
**113**　[AtCoder Regular Contest 060 E - 高橋君とホテル](https://atcoder.jp/contests/arc060/tasks/arc060_c)　LCA ではないですが、ダブリングの発想を使って解けます。
**114**　[JOI 2010 本選 5 - JOI 国のお祭り事情](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0575)　超難問のチャレンジ問題です。橙色コーダー相応以上の難易度がありますが、是非挑戦してみましょう。

#### Grundy 数
**115**　[AtCoder Regular Contest 013 C - 笑いをとれるかな？](https://arc013.contest.atcoder.jp/tasks/arc013_3)
**116**　[AOJ 0401 - 石遊び](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0401&lang=ja)
**117**　[AtCoder Grand Contest 017 D - Game on Tree](https://atcoder.jp/contests/agc017/tasks/agc017_d)　AtCoder 1100 点のチャレンジ問題です。黄色～橙色コーダー相応の難易度があります。

#### Rolling Hash
**118**　[ALDS_14_B - 文字列検索](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_14_B&lang=ja)　基本問題です。
**119**　[AtCoder Beginner Contest 141 E - Who Says a Pun?](https://atcoder.jp/contests/abc141/tasks/abc141_e)
**120**　[AtCoder Beginner Contest 135 F - Strings of Eternity](https://atcoder.jp/contests/abc135/tasks/abc135_f)
**121**　[AtCoder Beginner Contest 150 F - Xor Shift](https://atcoder.jp/contests/abc150/tasks/abc150_f)　文字列ではないですが Rolling Hash が使える問題です。ちなみに、Rolling Hash は文字列上だけでなく配列にも適用することができます。

#### 平方分割
**122**　[全国統一プログラミング王決定戦本戦 D - Deforestation](https://atcoder.jp/contests/nikkei2019-final/tasks/nikkei2019_final_d)　バケット法を使って、$O(N \sqrt{N})$ で解くことができます。

※ セグメント木のところで紹介しますが、

* [Range Minimum Query (RMQ)](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_A)
* [Range Sum Query (RSQ)](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_B&lang=ja) 

といった問題も平方分割で解くことができます。もちろん、セグメント木を使うと解くことができますが、平方分割で解いてみてもいいかもしれません。

#### 最大流／最小カット
**123**　[GRL_6_A - Maximum Flow](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A)　基本問題です。
**124**　[AtCoder Beginner Contest 010 D - 浮気予防](https://atcoder.jp/contests/abc010/tasks/abc010_4)　最小カット問題に帰着することができます。
**125**　[AtCoder Regular Contest 074 F - Lotus Leaves](https://atcoder.jp/contests/arc074/tasks/arc074_d)　チャレンジ問題。2 個考察ステップが必要で、難しいです。

#### 二部グラフを扱う問題
**126**　[CODE FESTIVAL 2017 Qual B C - 3 Steps](https://atcoder.jp/contests/code-festival-2017-qualb/tasks/code_festival_2017_qualb_c)

#### 二部マッチングを扱う問題
**127**　[GRL_7_A - Bipartite Matching](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_7_A&lang=ja)　基本問題です。
**128**　[AtCoder Beginner Contest 091 C - 2D Plane 2N Points](https://atcoder.jp/contests/abc091/tasks/arc092_a)　貪欲法でも解けますが、二部マッチングでも是非解いてみてください。
**129**　[AOJ 1163 - Cards](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1163)
**130**　[SoundHound Inc. Programming Contest 2018 (春) C - 広告](https://atcoder.jp/contests/soundhound2018/tasks/soundhound2018_c)　ヒント：二部グラフの[最大独立集合](https://www.weblio.jp/content/%E6%9C%80%E5%A4%A7%E7%8B%AC%E7%AB%8B%E9%9B%86%E5%90%88%E5%95%8F%E9%A1%8C)のサイズは、頂点数から二部グラフの最大マッチングを引いたものです。
**131**　[AtCoder Regular Contest 013 D - 切り分けできるかな？](https://atcoder.jp/contests/arc013/tasks/arc013_4)　チャレンジ問題。50 問の中で最難問の 1 つです。

#### Binary Indexed Tree (BIT) を使う問題
**132**　[DSL_2_B - Range Sum Query](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_B&lang=ja)　基本問題です。
**133**　[DSL_2_D - Range Add Query](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_E&lang=ja)　基本問題です。
**134**　[ALDS_5_D - 反転数](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_5_D&lang=ja)　基本問題です。
**135**　[AOJ 0365 - 文字列スワップ](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0365&lang=ja)　反転数を少し応用させた問題です。
**136**　[AtCoder Regular Contest 033 C - データ構造](https://arc033.contest.atcoder.jp/tasks/arc033_3)
**137**　[AtCoder Beginner Contest 136 F - Enclosed Points](https://atcoder.jp/contests/abc136/tasks/abc136_f)
**138**　[JOI 2011 本選 5 - 微生物実験](https://atcoder.jp/contests/joi2011ho/tasks/joi2011ho5)　チャレンジ問題です。

#### Range Minimum Query (RMQ)
**139**　[DSL_2_A - Range Minimum Query](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_A)　基本問題です。
**140**　[AtCoder Grand Contest 004 B - Colorful Slimes](https://atcoder.jp/contests/agc004/tasks/agc004_b)

#### 遅延評価セグメント木
**141**　[DSL_2_F - RMQ and RUQ](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_F&lang=ja)　基本問題です。
**142**　[DSL_2_H - RMQ and RAQ](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_H&lang=ja)　基本問題です。
**143**　[Square869120Contest #2 H - Counting 1's](https://atcoder.jp/contests/s8pc-2/tasks/s8pc_2_h)
**144**　[JOI 2008 春合宿 - Typhoon](https://atcoder.jp/contests/joisc2008/tasks/joisc2008_typhoon)
**145**　[JOI 2012 春合宿 - Fortune Telling](https://atcoder.jp/contests/joisc2012/tasks/joisc2012_fortune_telling)
**146**　[「みんなのプロコン」2017 予選 D - 工場](https://atcoder.jp/contests/yahoo-procon2017-qual/tasks/yahoo_procon2017_qual_d)

#### その他のテクニック
計算幾何のアルゴリズムのうち一つ、「[偏角ソート](https://qiita.com/ganariya/items/adef1a7f89ae88b804da)」によって解ける問題たちです。

**147**　[AtCoder Beginner Contest 033 D - 三角形の分類](https://atcoder.jp/contests/abc033/tasks/abc033_d)
**148**　[AtCoder Beginner Contest 139 F - Engines](https://atcoder.jp/contests/abc139/tasks/abc139_f)

最短経路アルゴリズムの一つ、「[拡張ダイクストラ法](https://qiita.com/ageprocpp/items/cdf67e828e1b09316f6e#%E6%8B%A1%E5%BC%B5%E3%83%80%E3%82%A4%E3%82%AF%E3%82%B9%E3%83%88%E3%83%A9)」によって解ける問題たちです。

**149**　[JOI 2017 予選 6 - ヘビの JOI 君](https://atcoder.jp/contests/joi2017yo/tasks/joi2017yo_f)
**150**　[いろはちゃんコンテスト Day2 G - 通学路](https://atcoder.jp/contests/iroha2019-day2/tasks/iroha2019_day2_g)

---

これが全部解けたら、自信もって「黄色コーダー相当のアルゴリズム構築能力と実装力がある」といってよいです。あとは [3-2-3. 節](https://qiita.com/e869120/items/acba3dd8649d913102b5#3-2-3-topcoder-srm-%E3%81%AE%E5%95%8F%E9%A1%8C%E3%82%92%E8%A7%A3%E3%81%84%E3%81%A6%E6%95%B0%E5%AD%A6%E7%9A%84%E8%80%83%E5%AF%9F%E5%8A%9B%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B) で述べたように、TopCoder の SRM を解いて数学的考察力を上げれば、きっと黄色コーダーになれるでしょう。
<br />

# 3-4. 「競プロ典型 90 問」のすすめ（2021/7/12 追記）
ここまで、中級編と上級編では、以下の問題集を紹介しました。

* [2-3. 節｜分野別　初中級者が解くべき過去問精選 100 問](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)
* [3-3. 節｜分野別　上級者が解くべき過去問精選 100 + 50 問](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)

しかし、これには「過去問である」「解説が整備されていない問題もある」などのデメリットがあります。また、AtCoder では**アルゴリズム**・**考察テクニック**の両方が重要であるにも関わらず、後者を対策できる問題が 10 問程度しか収録されておらず、アルゴリズムにかなりの重点を置いています。

このような欠点を解消しようと思い、2021 年に入り

* [競プロ典型 90 問](https://atcoder.jp/contests/typical90)

という新たな教材が生まれ、同年 7/11 に完成しました。（これも私が作成した教材です）

---

競プロ上級者を目指すために必要な問題が 90 問集まっているほか、問題のレベルは AtCoder Beginner Contest の C ～ F 問題と幅広く、難易度別に分けられています。したがって、「簡単な問題の復習」「典型知識の習得」の両方の用途に使えます。

また、下図のように**キーワードが書かれた解説**もあり、要点が整理しやすいです。そして、自分のプログラムが正しいかどうかを確認できる「ジャッジシステム」が AtCoder に用意されているため、効率よく練習を行うことができます。
![11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/09bd5d15-0287-0adc-0be0-c54edce803e7.jpeg)
特に、レーティングが **<font color="#804000">400（茶色）</font>～<font color="#C0C000">2299（黄色中位）</font>** の参加者にはお勧めできます。この教材について詳しく知りたい方は、

* [AtCoder での実力アップを目指そう！　～競プロ典型 90 問～](https://qiita.com/e869120/items/1b2a5f0f07fd927e44e9)

をご覧ください。


<br />

# 3-5. 「黄色コーダー」を目指す人のための Tips 4 個
3 章の最後に、<font color="#AAAA00">**黄色コーダー**</font>を目指す皆さんにとって便利な情報をいくつか紹介したいと思います。

## 3-5-1. 海外コンテストサイトのすすめ
皆さんは、AtCoder というコンテストサイトで競プロをやっていると思います。しかし、AtCoder では週に 1 回しかコンテストがありません。そうすると、

> 「実力を上げるためにもっとコンテストに出たい！」

と思う人もいると考えられます。そこでお勧めなのは、「海外のコンテストに参加する」という手段です。その中でも最もやりやすいのは、ロシアの

* [CodeForces](https://codeforces.com/)

というコンテストサイトです。

#### CodeForces の利点
週に 2, 3 回もコンテストをやってくれるので、コンテストに出たい人にとってはお得です。例えば 2020/2/9 ～ 2/18 の僅か 10 日間で 5 回もコンテストが開催されています。
![29.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/3ec5e6a5-3c48-8128-aadd-a02aa2207645.png)

#### CodeForces の欠点と、その解決法
* 開始時刻が 24 ～ 26 時とかになることが多く、夜が遅いことです。
    * 海外のコンテストなので、時差の関係で日本では深夜開催になってしまいます。
    * ただし、毎回がそうという訳ではなく、開催時刻が早く参加できるコンテストもあります。
    * 出れなかったコンテストの問題は、過去問として（あるいはバーチャル参加で）解けばよいです。
* 問題文が英語であることです。
    * いずれ英語は必要になるので、少なくとも競プロの問題文を読めるくらいまでのレベルまでは、英語を勉強することをお勧めします。

## 3-5-2. 競プロ作問のすすめ
日本には、AtCoder だけではなく、[yukicoder](https://yukicoder.me/) という比較的ゆるふわなコンテストサイトがあります。yukicoder の最大の特徴として挙げられるのは、レート帯に関わらず、だれでも作問をすることができることです。

何故競プロ作問は良いのでしょうか。この理由は 2 つあります。

* 自ら問題を作ってみることで、アルゴリズムへの理解が深まるうえ、作問者の意図を感じることができる。それらは実力の向上につながる。
* 「作問」という新しいことをやってみることで、競プロのモチベーション維持につながる。

さて、どのようにして作問をすれば良いのでしょうか。[yukicoder](https://yukicoder.me/) や AtCoder 非公式コンテストなどで作問をする方法・テクニックは、以下の記事にまとまっています。

* [競技プログラミングにおける作問テクニックを総整理！ 〜初心者から経験者まで〜](https://qiita.com/e869120/items/45a0132263094b83fc44)

という訳で、もし宜しければ、皆さんも一度競プロ作問をやってみませんか。

## 3-5-3. 過去問は何分で解説を見れば良いのか？
さて、過去問を解いてそもそも解法が全然分からないとき、いつになったら解説を読めば適切なのかわからない人が多いと思います。そこで、経験則からの大体の目安を提示しておきます。

| |100 点 |200 点 |300 点 |400 点 |500 点 |600 点 |700 点 |800 点 |900 点 |
|---|---|---|---|---|---|---|---|---|---|
|水色コーダー |3 分 |4 分 |10 分 |25 分 |45 分 |90 分 |120 分 | | |
|青色コーダー |2 分 |3 分 |6 分 |20 分 |40 分 |80 分 |100 分 |120 分 | |
|黄色コーダー |1 分 |2 分 |4 分 |15 分 |35 分 |60 分 |80 分 |100 分 |120 分 |
|橙色コーダー |15 秒 |1 分 |3 分 |10 分 |30 分 |45 分 |60 分 |80 分 |110 分 |
比較的簡単な問題にも関わらず解法がわからない場合、「典型知識や典型テクニックを知らないから解けなかった」という可能性がとても高いです。そのため、早めに解説を見ることをおすすめします。<font color="#FF0000">(2/20 00:47 PM. 追記)</font>

※ 茶色コーダー・緑コーダーの場合は[こちら](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-4-3-%E9%81%8E%E5%8E%BB%E5%95%8F%E3%81%AF%E4%BD%95%E5%88%86%E3%81%A7%E8%A7%A3%E8%AA%AC%E3%82%92%E8%A6%8B%E3%82%8C%E3%81%B0%E3%82%88%E3%81%84%E3%81%8B)を参照。
※ 答えるのにかかった時間ではなく、解法が分からなかった時間です。

## 3-5-4. ライブラリ整備のすすめ
皆さんの中に、こういう考えを持っている人はいますか。

> 例えばセグメント木とか RMQ とか BIT とか UnionFind とか、いちいち書いていると時間がかかって面倒なのではないか。これをどうにかして節約できないか。

この問題を解決する手段の一つが**ライブラリ整備**です。予め各種アルゴリズムの実装ソースコードを作っておき、コンテスト時にはそのソースコードを貼り付けるだけにする、という手法です。（以下、ライブラリ整備の例です。セグメント木や幾何ライブラリなどを整備しています。）
![30.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/95b10c09-7b0f-d95a-4802-da834db2a6c5.png)
※ AtCoder ではライブラリが使えますが、中高生が出場できる大会の一つ「[日本情報オリンピック](https://www.ioi-jp.org/)」の本選・春合宿本番ではライブラリが使えないことにご注意ください。
<br />

# 4. 「橙色コーダー」になるためには何をすれば良いのか
3 章では、<font color="#AAAA00">**黄色コーダー**</font>に到達には何が要求されるのか、到達するまでの練習方法、意識すべきポイントなどについて記しました。

本章では、<font color="#AAAA00">**黄色コーダー**</font>から、一個上のランクである<font color="#FF7700">**橙色コーダー**</font>に上がるためには、何をすれば良いのかを記します。

## 黄色と橙色の差は「演習量」
黄色コーダーから橙色コーダーにかけて、学ぶべきアルゴリズムはそれほど増えません。

一方で、レーティングが 2000 以上となると AtCoder Beginner Contest におけるレーティングの変動が無くなるなどといった理由で、レーティングを上げるために解くべき問題のバリエーションが一気に増えます。そのため、演習量が大切になってきます。実際に、[mencotton さんのツイート](https://twitter.com/men_cotton/status/1218144242238775297) によると、以下の統計情報が明らかになっています。<font color="red">（2020/01/17 時点の統計です）</font>

|条件 |60% ライン |90% ライン |
|---|---|---|
|黄色コーダー達成 |1510 問 AC |1880 問 AC |
|橙色コーダー達成 |1910 問 AC |2200 問 AC |

つまり、黄色コーダー達成から橙色コーダー達成まで、**およそ 400 問**解く必要があったケースが多い、ということが分かります。
![40.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/90df3931-8f92-5b98-c08d-707acdf34183.png)

しかし、重要なのは**解く問題の数**だけではありません。橙コーダーになると、

* 「早解き力」　　だけでなく
* 難しい問題を解く力

も重要になってくるのです。その難問をコンテスト時間いっぱい使って解けるようになるためには、どのような練習をすれば良いのでしょうか。

## 難問を時間かけて解く練習が重要
難しい問題をコンテストで解けるようになるためには、

* [AtCoder Problems](https://kenkoooo.com/atcoder/#/table/)　における<font color="#FF7700">**橙後半相応（2600+）**</font>～<font color="#FF0000">**赤色コーダー相応**</font>の難易度を、時間かけて解く

ことが練習として良いと思います。[^3]

最初は 1 問当たり 2 時間くらいかかったり、2 時間あっても解けないことがあると思います。それは高難易度帯の考察をやったことがないので当然です。しかし、難問を 50 問くらい解いていくうちに、数問に 1 問の割合で解けるようになっていきます。

橙後半相応の難易度の問題を 1 時間以内で解ける確率が 2-3 割になると、橙色コーダーの実力が付いたといえるでしょう。

## 難問を解くにあたって重要なこと
最後に、難問を解くにあたって重要なことをいくつか紹介します。

#### 1 点目
解説は見ないことをお勧めします。
そのくらいの難易度になってくると、たくさん考えた分だけ、考察力が付くからです。また、「どんな感じで解法が見えたのか」というのが分かれば復習などに役立てることができますが、それは自力で解けたときにしかわかりません。その点でも、自力で解くことは大切です。

#### 2 点目
さて、どのタイミングで問題を解くのを諦めれば良いのでしょうか。
解法を考える時間だけで **120 分程度**使っても解法が分からなかった場合は、この問題を諦めて別の問題を解くことをお勧めします。なお、2 週間～数カ月くらい経ってから、以前諦めた問題に再挑戦するのはとても良い方法です。それが解けたときの達成感はとても大きく、モチベーションの維持にもつながります。

#### 3 点目
過去問を解くときに、集中するときと集中しないときでは効率が全然違います。
一方、難問を解くためには 2 時間や 3 時間など長い時間を使う必要があることが多いです。そのため、集中力が切れやすいです。集中力を維持する一つの手段としては、**タイマーで時間を測る**と良いです。難問を解く練習には、それほど早解き力は必要ないですが、集中力の維持という別の目的でタイマーが有効だと考えられます。
<br />

# 5. 「橙色コーダー」の先　～ガチンコ競技としての競プロのはじまり～
日本で橙色コーダー以上の参加者は、僅か 104 人しかいません。[^4]
![33.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507979/e1dacbef-775c-08c6-52cc-c26f61495a76.png)
しかし、そのような人にしか見られない景色があるのです。これは、「ガチンコ競技としての競プロ」をより強く感じ始めるということです。橙色コーダー以上の強い人は、

* 企業コンテストの本戦に行くことができる機会が多い
* [国際情報オリンピック (IOI)](https://ja.wikipedia.org/wiki/%E5%9B%BD%E9%9A%9B%E6%83%85%E5%A0%B1%E3%82%AA%E3%83%AA%E3%83%B3%E3%83%94%E3%83%83%E3%82%AF) や [ACM国際大学対抗プログラミングコンテスト](https://ja.wikipedia.org/wiki/ACM%E5%9B%BD%E9%9A%9B%E5%A4%A7%E5%AD%A6%E5%AF%BE%E6%8A%97%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88)の世界大会を見据え始める

といった感じになり、一気に「競技をやってる感」が増します。

例えば、企業コンテスト本戦の場合、予選を勝ち抜いた参加者は現地会場に集まって、同じ部屋でコーディングをします。[第一回日本最強プログラマー学生選手権決勝](https://atcoder.jp/contests/jsc2019-final)の場合、200 人が大会本番の緊張した雰囲気の中コーディングをするのです。しかも賞金がかかっており、[全国統一プログラミング王決定戦](https://events.nikkei.co.jp/21116/)の場合、優勝賞金は 50 万円と非常に高額です。

そのように、<font color="#FF7700">**橙色コーダー**</font>以上、特に<font color="#FF0000">**レッドコーダー**</font>になると、ガチンコ競技としての、そしてスポーツとしての新しい競プロの世界が見え始めるのです。

目指せレッドコーダー！
<br />

# 6. おわりに
競技プログラミングの世界はとても広いです。だからこそ、楽しい側面もあれば、実力がそう簡単に上がらないという厳しい側面もあります。その分、競プロで上達するのはとても嬉しいことです。

最後に、本記事が一人でも多くの「競プロで上達したい」と思っている AtCoder 参加者の役に立つことができれば、とても嬉しい気持ちです。記事を最後までお読みいただき、ありがとうございました！

## 謝辞
今回は、競技プログラミングで上達するためのガイドラインを書いてみるという試みをしました。これはおそらく、少なくとも私が調べた中では初めての試みです。

そんな中、本記事を執筆するにあたり、たくさんの方々に支えていただきました。今の素晴らしい AtCoder を提供してくださった chokudai さん、各種アルゴリズムの記事を引用させていただいた drken さん、iwiwi さん、satanic0258 さん、ganariya さん、Kutimoti さん、hamayanhamayan さん、ageprocpp さん、mickey24 さん、imos さん、maskot1977 さん、ofutonfuton さん、python_walker さん、baitop さん、Pocala さん、cinnamo-coder さん、Yang33-kassa さん、prd-xxx さん、tsutaj さん、pokutuna さん、過去問精選 150 問それぞれの素敵な問題を提供してくださった方々、読んでくださった読者の皆さん、そして競技プログラミングに関わるすべての方々に感謝申し上げます。本当にありがとうございました。

[^1]: 2020 年 8 月 3 日時点。
[^2]: ソースは [0214sh7 さんのツイート](https://twitter.com/0214sh7/status/1203947206924877824)です。この統計資料は 2019 年 12 月 9 日に私（E869120）が調査したものであり、ここではその統計資料を全体に広めた 0214sh7 さんのツイートを引用しています。（2/20 08:11 PM. 追記）
[^3]: 私が橙色コーダーから赤色コーダーになるために使った練習方法ですが、橙色コーダーにより高い確率でなりたい場合、黄色コーダーの時点でその練習方法を使うこともおすすめです。
[^4]: 2020 年 8 月 3 日時点。