Slide 1

Slide 1 text

ABC 緑 diff を攻略する @furuya1223

Slide 2

Slide 2 text

/72 対象読者 u AtCoder のレートが灰〜緑(〜⽔⾊)の⼈ u AtCoder Problems における difficulty が緑の問題を 安定して解きたい⼈ ※ AtCoder Problems: kenkoooo さんによる超すごいサイト https://kenkoooo.com/atcoder#/table/ 2

Slide 3

Slide 3 text

/72 これは何︖ u 緑 diff の問題を攻略するコツを解説 u 知識よりも考察のしかたを中⼼に扱う u 要求される知識の紹介もする(紹介だけ) u ⾔語仕様への⾔及では C++14 のみ扱う 3

Slide 4

Slide 4 text

/72 ⽬次 u p5. 競プロで測られる能⼒ u p8. 強くなるために必要なもの u p19. 緑 diff で要求される知識 u p31. 考察のコツ ←これがメイン u p42. 練習⽅法のアドバイス u p44. おわりに u p68. 考察のコツ(過去問との対応) ←解法ネタバレ含む 4

Slide 5

Slide 5 text

5/72 競プロで測られる能⼒ 5

Slide 6

Slide 6 text

/72 競プロで測られる能⼒とは︖ (ここから全部私⾒) u 問題を既知の枠組みで解ける問題に変換する能⼒ u 数学・計算機科学の知識や経験 u プログラミングの知識・コーディング能⼒ 6

Slide 7

Slide 7 text

/72 競プロで測られる能⼒とは︖ (ここから全部私⾒) u 問題を既知の枠組みで解ける問題に変換する能⼒ u 数学・計算機科学の知識や経験 u プログラミングの知識・コーディング能⼒ 知識とコーディング能⼒だけではない︕ 7

Slide 8

Slide 8 text

8/72 強くなるために必要なもの 8

Slide 9

Slide 9 text

/72 そもそも「問題を解く」とは︖ u 与えられた問題を変換したり分解したりして u 簡単に解ける問題に持っていく u そして解く 9

Slide 10

Slide 10 text

/72 問題を解くイメージ 正解 ここからなら簡単に 正解にたどり着ける範囲 与えられた問題 10

Slide 11

Slide 11 text

/72 問題を解くイメージ 正解 ここからなら簡単に 正解にたどり着ける範囲 問題の変換 与えられた問題 11

Slide 12

Slide 12 text

/72 問題を解くイメージ 正解 ここからなら簡単に 正解にたどり着ける範囲 問題の変換 問題の分割 与えられた問題 12

Slide 13

Slide 13 text

/72 問題を解くイメージ 正解 ここからなら簡単に 正解にたどり着ける範囲 問題の変換 問題の分割 与えられた問題 ここまで来たら あとはやるだけ︕ 13

Slide 14

Slide 14 text

/72 問題を解けないイメージ 正解 ここからなら簡単に 正解にたどり着ける範囲 問題の分割 問題の変換 与えられた問題 14

Slide 15

Slide 15 text

/72 問題を解けないイメージ 正解 ここからなら簡単に 正解にたどり着ける範囲 問題の分割 問題の変換 知識・経験が⾜りない︕︕ 考察スキルが⾜りない︕︕ 与えられた問題 15

Slide 16

Slide 16 text

/72 強くなるために u 「やるだけゾーン」を広げる u 問題を変換する能⼒を⾝につける 16

Slide 17

Slide 17 text

/72 「やるだけゾーン」を広げる u 知識・経験を⾝につける u アルゴリズム・データ構造…… u 頻出パターン…… u たくさん解法を知るしか無い 17

Slide 18

Slide 18 text

/72 問題を変換する能⼒を⾝につける u 汎⽤性の⾼い考察パターンというものがある u それを紹介していきます 18

Slide 19

Slide 19 text

19/72 緑 diff で要求される知識 19

Slide 20

Slide 20 text

/72 ABC 緑 diff で要求される知識 u ABC 126 以降(2019/05〜)から分析 u 紹介するだけ u 個別の解説は各⾃で調べてください u 私のツイッターアカウントに聞いてくれてもOK 20

Slide 21

Slide 21 text

/72 ⾔語の知識 u int 型は 符号付き 32 bit 整数︓−2×10& ~ 2×10& ぐらい u long long 型は符号付き 64 bit 整数︓−9×10)* ~ 9×10)* ぐらい u double 型は⼩数を扱える.精度は 15 桁ほど u double で⼀致や⼤⼩⽐較をすると誤差でエラーになるかも u 負の数の除算や剰余算,計算途中のオーバーフローに注意 21

Slide 22

Slide 22 text

/72 数学の知識 u 剰余演算(mod)の知識 u mod 逆元・フェルマーの⼩定理 u 組合せの計算 u ⼆進数の計算 u 最⼤公約数・ユークリッドの互除法 u 素因数分解(約数の個数・エラトステネスの篩) 22

Slide 23

Slide 23 text

/72 計算量の基礎知識 u ビッグオー記法についてふんわりと理解 u 制約から,どれくらいのオーダーで間に合うか考えられる u 計算量に log がつくパターン u set, map, priority_queue, sort, ⼆分法・⼆分探索, N/1+N/2+...+N/N u ! 2# のパターン u bit 全探索 23

Slide 24

Slide 24 text

/72 C++14 標準で使える機能 u vector, string, pair, set, map, queue, deque, priority_queue, (tuple) u sort, begin/end, rbegin/rend u lower_bound, upper_bound, set.lower_bound u 範囲ベース for による set, map 等のループ u Union-Find ⽊は標準機能(︖︖︖) 24

Slide 25

Slide 25 text

/72 全探索を極める u bit 全探索 u ! 個のものを 2 つに分ける u ! 個のものからいくつか選ぶ(選ぶ・選ばない に分ける) u next_permutation による順列全探索 u " !! u ループの深さを可変にしたいなら再帰関数にする 25

Slide 26

Slide 26 text

/72 累積和関連 u 基本の累積和︓区間和の⾼速計算 u 累積 XOR,累積 GCD など他の計算への応⽤ u 両端から累積を計算して「1 つ以外」を⾼速計算 u (imos 法による被覆カウント) 26

Slide 27

Slide 27 text

/72 ⼆分探索・⼆分法 u 基本の書き⽅(いわゆる ”めぐる式” など) u 実数での⼆分法 u 誤差があるので回数固定 u 相対誤差的に ! = #$ が良いらしい u lower_bound, upper_bound の活⽤ u 尺取法で解ける場合もある 27

Slide 28

Slide 28 text

/72 グラフを扱う u ⽤語を知る u 辺・頂点・有向/無向・連結・単純・パス・⽊ u 隣接リスト表現で実装する u DFS, BFS で探索をする u DFS は再帰関数,BFS は queue を⽤いる u BFS は辺コストが 1 のグラフの最短経路問題に使える 28

Slide 29

Slide 29 text

/72 シンプルな DP を知る u Educational DP Contest の A 問題から E 問題まで u ナップザック問題も上記に含まれる(D, E 問題) 29

Slide 30

Slide 30 text

/72 デバッグ⼒(りょく) u バグあるあるポイントを把握 u 負数の除算・剰余算,計算途中のオーバーフロー,領域外アクセス, 変数名間違い,同名の変数の定義,不等式の等号有無,再帰の終了条件, …… u テストケースを⼿作りする u 極端なケース u 普通のケース u 計算途中のものを表⽰させてみる(printf デバッグ) 30

Slide 31

Slide 31 text

31/72 考察のコツ 31

Slide 32

Slide 32 text

/72 いよいよ本編 u 本章ではネタバレ回避のため,項⽬の紹介だけ u 具体的な問題に適⽤する例は次章で解説 u 次章は ABC 過去問の緑 diff 問題の解法ネタバレを含む 32

Slide 33

Slide 33 text

/72 無駄に効率化しようとしない u ダサくても確実に正解できるならそれがベスト u 全通り試せるなら全通り試す u シンプルに考える u オシャレに解く必要は無い 33

Slide 34

Slide 34 text

/72 制約・問題設定から情報を得る u 変数の上限値から計算量を予測する u たまに外れる u 変な設定があったら理由を考えてみる u そうじゃなかったら困るのか︖ u どうやったらその設定を活かせるか︖ u 考えすぎ注意 u 特に上限値が⼩さい変数があれば,それを基準に考える 34

Slide 35

Slide 35 text

/72 詰まったら実験してみる u ⼩さいケースで全探索してパターンを⾒つける u ⼿計算する過程で気づくことがあるかも u 紙とペン(に類するもの)で書いてみることが⼤事 u ノートを惜しむべからず u 惜しむ場合は⼤量のコピー⽤紙などを買いましょう 35

Slide 36

Slide 36 text

/72 問題を変換する u 固定値と変動値を⼊れ替えてみる u 数式で記述してみる u 判定問題を考えてみる u 簡単バージョンで解けるか考えてみる u ⽊ → ⼀本道 など u 累積和や差分などに対する問題にしてみる 36

Slide 37

Slide 37 text

/72 複数の要素に分解する u 縦と横を独⽴に考えることを検討 u 各桁ごとに独⽴に考えることを検討 u 操作回数を決める問題と内容を決める問題に分けてみる 37

Slide 38

Slide 38 text

/72 順番について考える u 逆順に⾒てみるとなにか気づくかも u 順番は重要か考える u 重要でないなら,都合のいいように並べ替える 38

Slide 39

Slide 39 text

/72 1 つだけ決めてみる u 全部決めるのが難しくても 1 つなら決められる場合がある u 1 つ決まると連鎖的に残りが決まる場合がある u 1 つを頑張って決める u 1 つを適当に決めて最後に帳尻合わせをする 39

Slide 40

Slide 40 text

/72 操作を扱うテクニック u 逆順に⾒てみる u 複数の操作に共通する要素を考える・操作を同⼀視する u 操作によって不変な量を考える u 列の区間に対する操作 → 差分を持つと 2 箇所への操作になる 40

Slide 41

Slide 41 text

/72 数え上げのテクニック u 補集合を数えてみる u 組合せ数学をやる︕︕︕ 41

Slide 42

Slide 42 text

42/72 練習⽅法のアドバイス 解法ネタバレを含む解説の章は 4 枚後にあります 42

Slide 43

Slide 43 text

/72 私のブログ記事を⾒て(宣伝) u 競プロ脱超初⼼者のコツ(Beginners Selection解説) u https://www.creativ.xyz/editorial-beginners-selection-992/ u AtCoder ⻩⾊になる⽅法 u https://www.creativ.xyz/atcoder-yellow-596/ u DP⼊⾨︓Educational DP Contest A・B u https://www.creativ.xyz/edpc-a-b-1023/ u AtCoder Typical DP Contest – A「コンテスト」その1 u https://www.creativ.xyz/tdpc-a-1-660/ u 怠惰でもできる精進 u https://www.creativ.xyz/dont-say-lazy/ 43

Slide 44

Slide 44 text

44/72 おわりに 解法ネタバレを回避するために終わりじゃない場所に来てしまった 44

Slide 45

Slide 45 text

/72 緑 diff,難しい u 「緑 diff の解説ならサクッと作れるかな〜」と思っていた u そんなことはなかった u 要求される知識と考察のレベルはかなり⾼い u 緑 diff 安定=⽔⾊ぐらいの⼈はすごい u ⽔⾊以上を⽬指して頑張りましょう︕ 45

Slide 46

Slide 46 text

46/72 考察のコツ(過去問との対応) 46

Slide 47

Slide 47 text

/72 具体的な事例を紹介 u ABC 緑 diff の過去問についてネタバレを含む u 考え⽅の解説だが,実質的に解法の解説になるかも u 順番はバラバラ(前章で紹介した順に) 47

Slide 48

Slide 48 text

/72 ABC160 D Line++ u 概要 u ⼀本道グラフに 1 本だけ辺を追加 u 最短距離が ! になる頂点対の個数は︖(全 ! について) u 無駄に効率化しようとしない u 全頂点対について最短距離が " 1 で分かれば良い u シンプルさのために無駄な考慮を許容する u 追加辺を使う場合・使わない場合の両⽅計算して⼩さい⽅ 48

Slide 49

Slide 49 text

/72 ABC152 D Handstand 2 u 概要 u ! 以下の数の組 (#, %) で,互いの末尾が⾃分の先頭になる組の数 u 無駄に効率化しようとしない u ! ≤ 2×10, なのですべての数を⾒ても間に合う u 先頭と末尾の数の組は 9. = 81 通り u 81 回全部⾒ても間に合う 49

Slide 50

Slide 50 text

/72 ABC151 D Maze Master u 概要 u グリッド迷路から 2 点選ぶ最⻑距離は︖ u 無駄に効率化しようとしない u !" ≤ 400 なので & !" ' でも間に合いそう u 始点決めて,終点決めて,距離計算,をそれぞれ & !" でできる u 距離計算は BFS で⾏うので,始点を決めたら全点への距離を計算 50

Slide 51

Slide 51 text

/72 ABC147 C HonestOrUnkind2 u 概要 u ! ⼈の正直者と不親切な⼈がいて,他者に関する証⾔がある u 正直者の数としてあり得る最⼤値は何⼈︖ u 無駄に効率化しようとしない u ! ≤ 15 なので全割当は 2& ≤ 32768 通り u 判定問題を考える u ある割当について「その割当は辻褄が合うか︖」を答える u 最⼤でも ! ! − 1 ≤ 210 回のチェックで済む 51

Slide 52

Slide 52 text

/72 ABC146 D Coloring Edges on Tree u 概要 u ⽊の辺に⾊を塗るが,1 つの頂点に同⾊の辺が接続しないように u 使う⾊数が最⼩のものを構築 u 無駄に効率化しようとしない u オシャレに解く必要はない u 愚直に「どう考えてもこれが最適」という⼿を重ねていく 52

Slide 53

Slide 53 text

/72 ABC128 C Switches u 概要 u 接続された複数のスイッチの ON 数の偶奇で点灯する電球がある u 全ての電球が点灯するスイッチの ON/OFF の組合せは何通り︖ u 無駄に効率化しようとしない u 全点灯になるスイッチ状態を数えようとしない u スイッチが最⼤ 10 個なので全状態を試してみる 53

Slide 54

Slide 54 text

/72 ABC163 D Sum of Large Numbers u 概要 u 10#$$, 10#$$ + 1, … , 10#$$ + ( から ) 個以上選ぶ和は何通り︖ u 制約・問題設定から情報を得る u 10#$$ という奇妙な数︓この問題では実質 ∞ u 選ぶ個数が異なれば和は絶対に異なる u 0, 1, … , ( から + 個選ぶときの和は何通り︖という問題を ) ≤ + ≤ ( + 1 のすべてで解ければ良い 54

Slide 55

Slide 55 text

/72 ABC161 D Lunlun Number u 概要 u 隣接する桁の数の差が 1 以下の数を「ルンルン数」とする u " 番⽬のルンルン数は︖ u 詰まったら実験 u 実際にルンルン数を⼩さい順に書き出してみる u 20〜30 個ぐらい書く u なにか⾒えてくるかも u ちなみにこの問題の editorial をいきなり⾒ても意味不明 55

Slide 56

Slide 56 text

/72 ABC153 E Crested Ibis vs Monster u 概要 u ! 番⽬の魔法はダメージ "# で消費 MP が $# u 体⼒ % のモンスターを倒すための最⼩の MP 消費量は︖ u 問題を変換する u ダメージ固定,消費 MP 変動 → 消費 MP 固定,ダメージ変動 u 「消費 MP が & のときに与えられる最⼤ダメージは︖」 u これが % 以上になる最⼩の & が答え 56

Slide 57

Slide 57 text

/72 ABC141 D Powerful Discount Tickets u 概要 u ! 枚使うと 1 品の値段が " #$ 倍(⼩数切り捨て)になる券が % 枚 u & 個の品物を買う合計⾦額の最⼩値は︖ u 問題を変換する u 割引券が 1 枚だけのパターンを考えてみる u 操作の順番が重要か考える u 割引券を 2 枚同時に適⽤するのと,1 枚ずつ適⽤するのは同じ︖ 57

Slide 58

Slide 58 text

/72 ABC138 D Ki u 概要 u 頂点が値 0 を持つ根付き⽊が与えられる u ある部分⽊全体に⼀定値を⾜す操作を繰り返す u 最終的な各頂点の値は︖ u 問題を変換する u ⽊だと難しいので,⼀本道のグラフで解けるか考えてみる u ⽊で DFS すると「根から⾃分までの⼀本道」を考慮できる 58

Slide 59

Slide 59 text

/72 ABC147 D Xor Sum 4 u 概要 u 正の数列が与えられる u 異なる 2 要素の XOR の総和は︖ u 独⽴な要素に分解する u AND, OR, XOR のビット演算では,各桁を独⽴に考えられる u 「 2 要素の XOR のうち,! 桁⽬が 1 になるものの個数」を計算 59

Slide 60

Slide 60 text

/72 ABC129 D Lamp u 概要 u グリッド上の 1 マスにランプを置く u 障害物に遮られず照らされる縦横のマス数は最⼤何マス︖ u 独⽴な要素に分解する u 縦と横を独⽴に考えられる.今回は右と左,上と下も︕ u 各マスについて「そこから右に何マス照らせるか」を計算 60

Slide 61

Slide 61 text

/72 ABC134 D Preparing Boxes u 概要 u ! 個の箱にボールを 0 個か 1 個⼊れる u 「$ の倍数の箱にあるボールの数の偶奇が %& になる」を満たしたい u ボールの⼊れ⽅を構築せよ u 1 つだけ決めてみる u 1 箇所,最初の段階でボールを⼊れるかどうかが確定する箱がある u 確定したら,残りの部分についても同じように考える u !/1 + !/2 + ⋯ + !/! = ,(! log !) に注意 61

Slide 62

Slide 62 text

/72 ABC133 D Rain Flows into Dams u 概要 u ! 個(奇数個)のダムが輪っかに並ぶ u 「ダム " − 1 とダム " に %& リットルずつ⾬が⼊った」という情報が ! 個 u 最終的な各ダムの⽔量が与えられるので,%& を計算 u 1 つだけ決めてみる u 1 つ決まると残りが連鎖的に決まる u 1 つを頑張って計算する or 適当に決めて帳尻合わせ u 数式で記述してみる 62

Slide 63

Slide 63 text

/72 ABC145 D Knight u 概要 u 「右 2 上 1 」もしくは「右 1 上 2 」で移動 u (0, 0) から (', () に⾏く⽅法は何通り︖ u 数式で記述してみる u 各移動の回数を ), * とすると 2) + * = ', ) + 2* = ( u これを解くと,移動の回数が決まる → 並べ替えのみ u 共通項を探す u どちらも座標の和が 3 増える → 移動回数は - = (' + ()/3 u どちらも (1, 1) 増える → 差し引くと 右 1 or 上 1 で (' − -, ( − -) へ 63

Slide 64

Slide 64 text

/72 ABC127 D Integer Cards u 概要 u 与えられた数列に複数の操作を順に⾏うとき,最終的な総和の最⼤値は︖ u 数を !" 個以下選んで,その数を #" に変える u 操作の順番は重要か︖ u 好きな順で操作しても良い → #" が⼤きいものから優先的に考える u 元の数列も順番はどうでもいいのでソートしてしまって良い u 問題を変換する u 書き換える数の個数を固定して考えてみる 64

Slide 65

Slide 65 text

/72 ABC140 D Face Produces Unhappiness u 概要 u 右向きと左向きの⼈が⼀列にならぶ u 区間を選んでぐるっと回転させる操作を任意回⾏う u 眼の前の⼈の後頭部を⾒る⼈の数の最⼤値は︖ u 補集合を数えてみる u 「向かい合う⼈の数の最⼩値は︖」 u 区間への操作は差分を⾒る u 向きが変わる場所と変わらない場所に着⽬してみる 65

Slide 66

Slide 66 text

/72 ABC132 D Blue and Red Balls u 概要 u ⻘⽟が ! 個,⾚⽟が " − ! 個ある u ⻘⽟の連続する区間が $ 個になるような並べ⽅は何通り︖ u 組合せ数学をやる︕︕︕ u ⾼校数学の「場合の数と確率」を勉強すると良い u コンビネーションを素数 MOD で計算することに慣れましょう 66

Slide 67

Slide 67 text

/72 ABC130 D Enough Array u 概要 u 与えられた数列で,区間和が ! 以上になる区間の個数は︖ u 補集合を数えてみる u 今回は難易度が変わらないけど,考えやすくなるかも u 区間を数えるためのテクニックを知る u 尺取法,⼆分法による端点の探索 67

Slide 68

Slide 68 text

68/72 おまけ︓紹介しなかった過去問 汎⽤パターンを当てはめにくかったやつ 68

Slide 69

Slide 69 text

/72 ABC160 E Red and Green Apples u 概要 u ⾚リンゴ,緑リンゴ,無⾊リンゴがいくつかある u ⾚を ! 個、緑を " 個⾷べて美味しさの合計を最⼤化したい u 無⾊リンゴは好きな⾊に変えて⾷べられる u ⾷べられるリンゴのうち最も美味しいものを⾷べ続ける u ⾷べられるリンゴの判定(特に無⾊)がちょっと⾯倒 u 無⾊リンゴは最後に⾊を決めれば良い 69

Slide 70

Slide 70 text

/72 ABC157 D Friend Suggestions u 概要 u ! ⼈の⼈について,友達関係とブロック関係が与えられる u 各⼈の,ブロックでも友達でもないが間接的に友達である⼈の数は︖ u 2 要素の関係はグラフにできる u グラフの連結成分は DFS か Union-Find ⽊ u 連結成分のサイズを持つ Union-Find ⽊を持っておくと良い u Union-Find ⽊で連結成分ごとに持つ値は根が持てば良い 70

Slide 71

Slide 71 text

/72 ABC148 E Double Factorial u 概要 u ! ! − 2 ! − 4 ⋯ の末尾につく 0 の個数は︖ u 末尾の 0 の個数= 10 で何回割れるか =「2, 5 で何回割れるか」の⼩さい⽅ u 階乗の素因数の個数の計算 → ルジャンドルの定理 u 仰々しい名前だけど中⾝はそんなに難しくない 71

Slide 72

Slide 72 text

/72 ABC142 D Disjoint Set of Common Divisors u 概要 u 正整数 !, # の公約数の中から,互いに素になるようにいくつか選ぶ u 選べる最⼤個数は︖ u 公約数=最⼤公約数の約数 u 素因数分解の計算量は $ % u % 以下の数で割れる限り割ったら,1 になるか素数が残るか 72