ARMERIA

Rubyと競技プログラミングの話 AtCoderやCodeforcesの問題解説記事が多め。

AtCoder

AtCoder Grand Contest 047 D - Twin Binary Trees

お題箱より。 D - Twin Binary Trees 解法 ちょうど2本の特殊辺を持つ単純サイクルは、第1の木の異なる2つの葉の組み合わせと同じ個数だけ存在します。このサイクルは、その2つの葉の第1の木におけるLCAと、それらと接続されている第2の木の2つの葉のLCAとを…

AtCoder Grand Contest 046 D - Secret Passage

お題箱より。 D - Secret Passage 解法 操作の特徴をつかむ 与えられる文字列 の長さを とします。また の 文字目を と表記します( 先頭は です)。 操作列によって文字列がどのようになるかを、まずは大雑把に理解しましょう。前から順に操作されるため、…

AtCoder Regular Contest 106 D - Powers

D - Powers 解法 である全てのペア について、【 と について対称な式】の値を合計せよ。 という問題設定はよく登場します。このような問題では、 という条件を外して かつ である全てのペア について、【 と について対称な式】の値を合計せよ。 と考えると…

AtCoder Grand Contest 048 B - Bracket Score

B - Bracket Score 解法 正しい括弧列の必要十分条件 いわゆる「正しい括弧列」の問題です。よく使われるアプローチとして累積和がありますが、今回は括弧が2種類あるので2つの累積和を管理する必要があり厳しそうです。 今回は別の性質を使うことにします。…

AtCoder Grand Contest 048 D - Pocky Game

D - Pocky Game 解法 各山の石の個数について、その初期値を と表し、ゲームの途中経過における値を と表すことにします。 まずは全ての状態を網羅するDPを もし石の総数が十分少なければ、以下のDPで全ての局面の勝敗状態を求めることができます。 :「先手…

個数制限付き部分和問題+条件を満たす選び方の数え上げ

先日のコンテストの問題における、最後の高速化について知りたいというリクエストがあったため、解説を書きます。より一般的な「個数制限付き部分和問題+条件を満たす選び方の数え上げ」という枠組みで説明します。 扱う問題 正整数 と、正整数からなる長さ …

AtCoder Regular Contest 104 E - Random LIS

E - Random LIS 公式解説とは違う解法です(たぶん)。 解法 あり得る全ての場合に対するLISの長さを合計して、全事象数 で割ることにします。 取っ掛かりが非常に掴みにくい問題ですが、 という制約から何らかの全探索をやることを目指してみます。 座標圧…

第三回 アルゴリズム実技検定 C - 等比数列

お題箱より。 C - Geometric Progression 解法というよりは「こういう問題を解くための思考プロセスが知りたい」というリクエストだったので、その方向で書きます。 解法 この問題は結局、等比数列の性質を知識として知っている、または実験によって理解する…

ACL Beginner Contest F - Heights and Pairs

F - Heights and Pairs 解法 まずは入力を各身長ごとの人数として集計します。 を身長が である人の人数とします。 であり、 人であるような身長を無視すれば身長の種類数は 以下です。 条件を満たす組み方をDPなどで直接数えようとすると、 から落ちず厳し…

ACL Beginner Contest E - Replace Digits

E - Replace Digits 先日、AtCoder Libraryの遅延伝播セグメント木の使い方について記事を書きました。 AtCoder LibraryのLazy Segtreeの使い方 - ARMERIA 今回の問題はセグ木にちょっと変なものを乗せる問題なので、上記の記事で解説していることの実践編と…

AtCoder LibraryのLazy Segtreeのチートシート

AtCoder LibraryのLazy Segtreeの使い方 - ARMERIA こちらの記事でAtCoder LibraryのLazy Segtreeの使い方を説明しましたが、コンテスト中に読んでられっか!みたいな時のためにコピペで使えるチートシートをまとめます。整数列に対する、以下の組み合わせ6…

AtCoder LibraryのLazy Segtreeの使い方

AtCoder Libraryが遅延伝播機能を持つセグメント木 atcoder::lazy_segtree を提供しているものの、何か渡すものいっぱいあるしドキュメントは数学用語だらけだしよく分からん!みたいな人向けの記事です。 問題を解いていて、セグメント木に必要な機能(区間…

キーエンス プログラミング コンテスト 2020 D - Swap and Flip

お題箱より。 D - Swap and Flip 解法 この問題のように「操作する場所を選んで、決められたルールに従って操作する」ということを繰り返す問題では、1回目の操作の選択、2回目の操作の選択…といった分岐パターンを直接探索していくのは非常に大変です。操作…

AtCoder Beginner Contest 178 F - Contrast

F - Contrast 解法が色々ある問題。シンプルで実装も楽な解法1と、私が本番で解いた解法2を証明付きで紹介します。前者のほうが断然オススメ。 解法1 まず 合計で 個を超える値が存在する場合、どのように並べても となる箇所が存在してしまいます。この場合…

AtCoder Library Practice Contest I - Number of Substrings

お題箱より。 I - Number of Substrings 解法 ※この問題における文字列 の部分文字列とは、 の連続な部分を取り出した文字列であることに注意してください。慣習的に、「部分列」と書くと連続とは限らない取り出し方、「部分文字列」と書くと連続な取り出し…

AtCoder Regular Contest 092 C - 2D Plane 2N Points

お題箱より。 C - 2D Plane 2N Points 以前の自分が解法の正当性を理解するのにすごく悩んだ問題で、印象深いです。 解法 考察 2次元の座標点を扱う際には「平面走査」というテクニックがよく使われます。これは座標点をある一方の座標、例えば 座標でソート…

DDCC 2016 本選 C - 特別講演「括弧列と塗り分け」

お題箱より。 C - 特別講演「括弧列と塗り分け」 解法 この問題を考えるにあたって重要なのが、正しい括弧列を根付き木と対応づけることです。 それぞれの括弧1組ずつを頂点とみなします。そしてその括弧の1つ外側を囲っている括弧を親とみなすように辺を張…

AtCoder Beginner Contest 170 E - Smart Infants

お題箱より。実装方法に関するリクエストだったので実装中心で書きます。 E - Smart Infants 解法 解法としてはシミュレーションです。園児が移動したときに、どのようなデータを管理しておけば効率的に答えを更新できるかを考えます。 今回は以下のようなデ…

CPSCO2019 Session3 F - Flexible Permutation O(N^2)解法

お題箱より。 解法が知りたいというリクエストだったので考えてみました。 F - Flexible Permutation 解法 後に扱うDPの都合上、個人的にはインデックスよりも値に注目したほうが理解しやすいので、条件を値中心の言葉に言い換えます。 であるような値 を「…

エイシング プログラミング コンテスト 2020 F - Two Snuke

F - Two Snuke 公式解説とは違う解法です。 解法 のときは答えは なので、 とします。 まずは 解法を まず答えを で求める方法を考えます。 の値を として、これを全通り試しましょう。そうすると、この を つに分ける分け方が 通りあります。 個並んだボー…

AtCoder Grand Contest 043 C - Giant Graph

お題箱より。 C - Giant Graph この問題は数ヶ月前に「なぜこの発想を思いつけるのか分からない」というリクエストをもらっていて、私にも分からなかったので記事を書けずにいました。でしたが、(同じ人が違う人かは分かりませんが)2つ目のリクエストをも…

Introduction to Heuristics Contest 参加記録

Introduction to Heuristics Contest - AtCoder 33位でした。 戦略 焼きなまし法を選択しました。 理由は、問題の性質として解の局所改善がやりやすく、スコアの差分計算を高速化して大量に回せそうだと考えたからです。対して、1手の変更がその後の展開を大…

AtCoder Beginner Contest 171 F - Strivore

F - Strivore 解法 文字列 の長さを とします。また最終的に出来上がる文字列を と表記します。 の長さは になります。そのうち元々あった文字と追加した文字の場所の割り当て方が 通りで、追加した文字の種類が 通りで…とやりたくなりますが、これでは最終…

AtCoder Grand Contest 046 C - Shift

C - Shift 解法 に含まれる 0 の個数を 、1 の個数を と書くことにします。 を、0 で区切られた 個のエリアに分割します。 図に示すように、エリア に含まれる 1 の個数を とし、エリア を含むそれ以前に含まれる 1 の個数を とします。 本問題の操作は、1 …

AtCoder Grand Contest 046 B - Extension

B - Extension 解法 まず以下のようなDPを考えてみましょう。 本問題の操作によって、縦 行、横 列になるまで操作してできる盤面の数 このDPで「上側に行を足し、その1つを黒く塗る」遷移と「右側に列を足し、その1つを黒く塗る」遷移をすれば良さそうですが…

AtCoder Beginner Contest 170 F - Pond Skater

F - Pond Skater 解法 1ターンに1マスの移動であればグリッド上のBFSで解けますが、今回は1ターンに マスまで動くことができます。これをそのままBFSで処理すると1つのマスから遷移可能なマスが最大 個になり、全体計算量 になって間に合いません。 具体的に…

東京海上日動 プログラミングコンテスト2020 D - Knapsack Queries on a tree

D - Knapsack Queries on a tree Editorialと同じ解法で解いたのでそっちを書きます。クエリごとに独立に解く方法もあって、そっちで解いた人のほうが多そうな印象です。 解法 が十分大きいという前提で解説をします。また扱う重みの最大値を 、最大深さの半…

AtCoder Grand Contest 045 C - Range Set

C - Range Set 解法 必要十分条件への言い換え ある01文字列が与えられた時に、それが操作によって生成可能であるかを判定することを考えます。 ここで今回のように「塗り潰す」系の操作の場合、「判定したい文字列から逆順で操作を行い、初期状態に戻せるか…

AtCoder Beginner Contest 011 D - 大ジャンプ

お題箱より。 D - 大ジャンプ 解法 まずは計算しやすいようにいくつか前処理をします。 ゴールまでの 軸方向それぞれの距離を で割ることで「正の方向にジャンプ○回分」という値に変換します。ここで割り切れない場合、答えは です。今後は で割った後の値を…

AtCoder Grand Contest 044 A - Pay to Win

A - Pay to Win 公式解説、丁寧だけど英語なんですよね…だいたいそのまま訳す感じの解説になってしまいそうですが許してください。 解法 操作を限定できる形に持ち込む いきなりですが、操作を逆から考えます。 気持ちとしては、 からの操作を考えるとどの遷…