Pro Yearly is on sale from $80 to $50! »

ABC 緑 diff を攻略する / The view of green-difficulty problems

ABC 緑 diff を攻略する / The view of green-difficulty problems

AtCoder Beginner Contest の緑 difficulty の問題を解くコツを自分なりにまとめたスライドです。
必要な知識の解説は無く、考察の方針がメインになっています。
(各自で調べられるよう、知識の紹介はしています)

前半の内容について、スライドで省いた説明などを補足する記事を書きました↓
https://www.creativ.xyz/the-view-of-green-difficulty-problems/

完全に私ふるやん(@furuya1223)の個人的見解ですのであしからず。

内容で参照されている私のブログ:http://www.creativ.xyz/

【用語解説】
AtCoder Beginner Contest ... プログラミングコンテストサイト AtCoder (https://atcoder.jp/home) で開催される初心者〜中級者向けコンテスト
緑 difficulty ... 有志作成の AtCoder Problems (https://kenkoooo.com/atcoder#/table) というサイトにおける難易度表示が緑帯であること

Da143b84d6bc6eed5f6dbce61f908559?s=128

ふるやん

May 01, 2020
Tweet

Transcript

  1. ABC 緑 diff を攻略する @furuya1223

  2. /72 対象読者 u AtCoder のレートが灰〜緑(〜⽔⾊)の⼈ u AtCoder Problems における difficulty

    が緑の問題を 安定して解きたい⼈ ※ AtCoder Problems: kenkoooo さんによる超すごいサイト https://kenkoooo.com/atcoder#/table/ 2
  3. /72 これは何︖ u 緑 diff の問題を攻略するコツを解説 u 知識よりも考察のしかたを中⼼に扱う u 要求される知識の紹介もする(紹介だけ)

    u ⾔語仕様への⾔及では C++14 のみ扱う 3
  4. /72 ⽬次 u p5. 競プロで測られる能⼒ u p8. 強くなるために必要なもの u p19.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  20. /72 ABC 緑 diff で要求される知識 u ABC 126 以降(2019/05〜)から分析 u

    紹介するだけ u 個別の解説は各⾃で調べてください u 私のツイッターアカウントに聞いてくれてもOK 20
  21. /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
  22. /72 数学の知識 u 剰余演算(mod)の知識 u mod 逆元・フェルマーの⼩定理 u 組合せの計算 u

    ⼆進数の計算 u 最⼤公約数・ユークリッドの互除法 u 素因数分解(約数の個数・エラトステネスの篩) 22
  23. /72 計算量の基礎知識 u ビッグオー記法についてふんわりと理解 u 制約から,どれくらいのオーダーで間に合うか考えられる u 計算量に log がつくパターン

    u set, map, priority_queue, sort, ⼆分法・⼆分探索, N/1+N/2+...+N/N u ! 2# のパターン u bit 全探索 23
  24. /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
  25. /72 全探索を極める u bit 全探索 u ! 個のものを 2 つに分ける

    u ! 個のものからいくつか選ぶ(選ぶ・選ばない に分ける) u next_permutation による順列全探索 u " !! u ループの深さを可変にしたいなら再帰関数にする 25
  26. /72 累積和関連 u 基本の累積和︓区間和の⾼速計算 u 累積 XOR,累積 GCD など他の計算への応⽤ u

    両端から累積を計算して「1 つ以外」を⾼速計算 u (imos 法による被覆カウント) 26
  27. /72 ⼆分探索・⼆分法 u 基本の書き⽅(いわゆる ”めぐる式” など) u 実数での⼆分法 u 誤差があるので回数固定

    u 相対誤差的に ! = #$ が良いらしい u lower_bound, upper_bound の活⽤ u 尺取法で解ける場合もある 27
  28. /72 グラフを扱う u ⽤語を知る u 辺・頂点・有向/無向・連結・単純・パス・⽊ u 隣接リスト表現で実装する u DFS,

    BFS で探索をする u DFS は再帰関数,BFS は queue を⽤いる u BFS は辺コストが 1 のグラフの最短経路問題に使える 28
  29. /72 シンプルな DP を知る u Educational DP Contest の A

    問題から E 問題まで u ナップザック問題も上記に含まれる(D, E 問題) 29
  30. /72 デバッグ⼒(りょく) u バグあるあるポイントを把握 u 負数の除算・剰余算,計算途中のオーバーフロー,領域外アクセス, 変数名間違い,同名の変数の定義,不等式の等号有無,再帰の終了条件, …… u テストケースを⼿作りする

    u 極端なケース u 普通のケース u 計算途中のものを表⽰させてみる(printf デバッグ) 30
  31. 31/72 考察のコツ 31

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

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

    33
  34. /72 制約・問題設定から情報を得る u 変数の上限値から計算量を予測する u たまに外れる u 変な設定があったら理由を考えてみる u そうじゃなかったら困るのか︖

    u どうやったらその設定を活かせるか︖ u 考えすぎ注意 u 特に上限値が⼩さい変数があれば,それを基準に考える 34
  35. /72 詰まったら実験してみる u ⼩さいケースで全探索してパターンを⾒つける u ⼿計算する過程で気づくことがあるかも u 紙とペン(に類するもの)で書いてみることが⼤事 u ノートを惜しむべからず

    u 惜しむ場合は⼤量のコピー⽤紙などを買いましょう 35
  36. /72 問題を変換する u 固定値と変動値を⼊れ替えてみる u 数式で記述してみる u 判定問題を考えてみる u 簡単バージョンで解けるか考えてみる

    u ⽊ → ⼀本道 など u 累積和や差分などに対する問題にしてみる 36
  37. /72 複数の要素に分解する u 縦と横を独⽴に考えることを検討 u 各桁ごとに独⽴に考えることを検討 u 操作回数を決める問題と内容を決める問題に分けてみる 37

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

  39. /72 1 つだけ決めてみる u 全部決めるのが難しくても 1 つなら決められる場合がある u 1 つ決まると連鎖的に残りが決まる場合がある

    u 1 つを頑張って決める u 1 つを適当に決めて最後に帳尻合わせをする 39
  40. /72 操作を扱うテクニック u 逆順に⾒てみる u 複数の操作に共通する要素を考える・操作を同⼀視する u 操作によって不変な量を考える u 列の区間に対する操作

    → 差分を持つと 2 箇所への操作になる 40
  41. /72 数え上げのテクニック u 補集合を数えてみる u 組合せ数学をやる︕︕︕ 41

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

  43. /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
  44. 44/72 おわりに 解法ネタバレを回避するために終わりじゃない場所に来てしまった 44

  45. /72 緑 diff,難しい u 「緑 diff の解説ならサクッと作れるかな〜」と思っていた u そんなことはなかった u

    要求される知識と考察のレベルはかなり⾼い u 緑 diff 安定=⽔⾊ぐらいの⼈はすごい u ⽔⾊以上を⽬指して頑張りましょう︕ 45
  46. 46/72 考察のコツ(過去問との対応) 46

  47. /72 具体的な事例を紹介 u ABC 緑 diff の過去問についてネタバレを含む u 考え⽅の解説だが,実質的に解法の解説になるかも u

    順番はバラバラ(前章で紹介した順に) 47
  48. /72 ABC160 D Line++ u 概要 u ⼀本道グラフに 1 本だけ辺を追加

    u 最短距離が ! になる頂点対の個数は︖(全 ! について) u 無駄に効率化しようとしない u 全頂点対について最短距離が " 1 で分かれば良い u シンプルさのために無駄な考慮を許容する u 追加辺を使う場合・使わない場合の両⽅計算して⼩さい⽅ 48
  49. /72 ABC152 D Handstand 2 u 概要 u ! 以下の数の組

    (#, %) で,互いの末尾が⾃分の先頭になる組の数 u 無駄に効率化しようとしない u ! ≤ 2×10, なのですべての数を⾒ても間に合う u 先頭と末尾の数の組は 9. = 81 通り u 81 回全部⾒ても間に合う 49
  50. /72 ABC151 D Maze Master u 概要 u グリッド迷路から 2

    点選ぶ最⻑距離は︖ u 無駄に効率化しようとしない u !" ≤ 400 なので & !" ' でも間に合いそう u 始点決めて,終点決めて,距離計算,をそれぞれ & !" でできる u 距離計算は BFS で⾏うので,始点を決めたら全点への距離を計算 50
  51. /72 ABC147 C HonestOrUnkind2 u 概要 u ! ⼈の正直者と不親切な⼈がいて,他者に関する証⾔がある u

    正直者の数としてあり得る最⼤値は何⼈︖ u 無駄に効率化しようとしない u ! ≤ 15 なので全割当は 2& ≤ 32768 通り u 判定問題を考える u ある割当について「その割当は辻褄が合うか︖」を答える u 最⼤でも ! ! − 1 ≤ 210 回のチェックで済む 51
  52. /72 ABC146 D Coloring Edges on Tree u 概要 u

    ⽊の辺に⾊を塗るが,1 つの頂点に同⾊の辺が接続しないように u 使う⾊数が最⼩のものを構築 u 無駄に効率化しようとしない u オシャレに解く必要はない u 愚直に「どう考えてもこれが最適」という⼿を重ねていく 52
  53. /72 ABC128 C Switches u 概要 u 接続された複数のスイッチの ON 数の偶奇で点灯する電球がある

    u 全ての電球が点灯するスイッチの ON/OFF の組合せは何通り︖ u 無駄に効率化しようとしない u 全点灯になるスイッチ状態を数えようとしない u スイッチが最⼤ 10 個なので全状態を試してみる 53
  54. /72 ABC163 D Sum of Large Numbers u 概要 u

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

    以下の数を「ルンルン数」とする u " 番⽬のルンルン数は︖ u 詰まったら実験 u 実際にルンルン数を⼩さい順に書き出してみる u 20〜30 個ぐらい書く u なにか⾒えてくるかも u ちなみにこの問題の editorial をいきなり⾒ても意味不明 55
  56. /72 ABC153 E Crested Ibis vs Monster u 概要 u

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

    枚使うと 1 品の値段が " #$ 倍(⼩数切り捨て)になる券が % 枚 u & 個の品物を買う合計⾦額の最⼩値は︖ u 問題を変換する u 割引券が 1 枚だけのパターンを考えてみる u 操作の順番が重要か考える u 割引券を 2 枚同時に適⽤するのと,1 枚ずつ適⽤するのは同じ︖ 57
  58. /72 ABC138 D Ki u 概要 u 頂点が値 0 を持つ根付き⽊が与えられる

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

    u 異なる 2 要素の XOR の総和は︖ u 独⽴な要素に分解する u AND, OR, XOR のビット演算では,各桁を独⽴に考えられる u 「 2 要素の XOR のうち,! 桁⽬が 1 になるものの個数」を計算 59
  60. /72 ABC129 D Lamp u 概要 u グリッド上の 1 マスにランプを置く

    u 障害物に遮られず照らされる縦横のマス数は最⼤何マス︖ u 独⽴な要素に分解する u 縦と横を独⽴に考えられる.今回は右と左,上と下も︕ u 各マスについて「そこから右に何マス照らせるか」を計算 60
  61. /72 ABC134 D Preparing Boxes u 概要 u ! 個の箱にボールを

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

    ! 個(奇数個)のダムが輪っかに並ぶ u 「ダム " − 1 とダム " に %& リットルずつ⾬が⼊った」という情報が ! 個 u 最終的な各ダムの⽔量が与えられるので,%& を計算 u 1 つだけ決めてみる u 1 つ決まると残りが連鎖的に決まる u 1 つを頑張って計算する or 適当に決めて帳尻合わせ u 数式で記述してみる 62
  63. /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
  64. /72 ABC127 D Integer Cards u 概要 u 与えられた数列に複数の操作を順に⾏うとき,最終的な総和の最⼤値は︖ u

    数を !" 個以下選んで,その数を #" に変える u 操作の順番は重要か︖ u 好きな順で操作しても良い → #" が⼤きいものから優先的に考える u 元の数列も順番はどうでもいいのでソートしてしまって良い u 問題を変換する u 書き換える数の個数を固定して考えてみる 64
  65. /72 ABC140 D Face Produces Unhappiness u 概要 u 右向きと左向きの⼈が⼀列にならぶ

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

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

    以上になる区間の個数は︖ u 補集合を数えてみる u 今回は難易度が変わらないけど,考えやすくなるかも u 区間を数えるためのテクニックを知る u 尺取法,⼆分法による端点の探索 67
  68. 68/72 おまけ︓紹介しなかった過去問 汎⽤パターンを当てはめにくかったやつ 68

  69. /72 ABC160 E Red and Green Apples u 概要 u

    ⾚リンゴ,緑リンゴ,無⾊リンゴがいくつかある u ⾚を ! 個、緑を " 個⾷べて美味しさの合計を最⼤化したい u 無⾊リンゴは好きな⾊に変えて⾷べられる u ⾷べられるリンゴのうち最も美味しいものを⾷べ続ける u ⾷べられるリンゴの判定(特に無⾊)がちょっと⾯倒 u 無⾊リンゴは最後に⾊を決めれば良い 69
  70. /72 ABC157 D Friend Suggestions u 概要 u ! ⼈の⼈について,友達関係とブロック関係が与えられる

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

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

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