Top

解法一覧 - ぺんぎんノート

:300点
:400点
:500〜600点
:700〜800点
問題を言い換える
複雑な問題でも、問題を言い換える(抽象度を上げる)ことでシンプルな問題になります。
情報を削ぎ落とす
  • 順序が意味を持たない数列は、集合と考える
  • 時系列を無視する
操作を逆順にする
そのままでは解けない問題が、操作を逆順にすることで解ける問題になることがあります。
値を求めようとするのではなく、既に値が求まっているものと考える
$A$で$B$を探索するのではなく、$B$で$A$を探索する
補集合を考える
偶奇で場合分けなど
再帰
全探索
bit全探索
$\sqrt N$個全探索
深さ優先探索
幅優先探索
累積和
加算、乗算、XOR、GCD、LCM、min、max。これらは結合則が成り立つため累積可能です。
約数の個数
約数の個数は、素因数分解したときのそれぞれの指数に1を足したものの積で表せます。たとえば$720$の約数の個数は、$720 = 2^4 + 3^2 + 5^1$、$(4 + 1)(2 + 1)(1 + 1) = 30$となり、$30$個だとわかります。この個数には、$1$や自分自身の数も含まれます。
個数の最大値(最小値)を、不等式を解いて求める
個数の最大値や最小値を求めるとき、解きたい問題を不等式で表した後、その不等式を式変形することで解くことができます。求めたいものが個数であるため、切り捨てや切り上げを使って整数にします。
コーナーケース
map
deque
動的計画法
DPっぽいけど制約で解けない
ソートして貪欲
何通りかを求めるときのDP
部分和問題のDP
最初を決めればすべてが決まる
最初を決めれば芋づる式にすべてが決まることがあります。このようなときは、最初を全探索すればよいです。
いもす法
バケツソート
最小公倍数
期待値の式変形
求めたい期待値を$X$とおいて式で表し、式変形することで解くことができます。
$X$と$Y$を独立して考える
$_nC_r$
半開区間$[A, B)$を、$[0, A)$と$[0, B)$に分解する
UnionFind
集合同士を結合したり、2つの要素が同じ集合に属するかどうかを高速に判定するデータ構造です。
数列$0, 1, 2, \ldots$の累積XOR和の周期性

初項0、公差1の等差数列の累積XOR和をとったときに周期性が現れます。

要素0123456789101112131415
XOR0130417081110121150
\begin{alignat*}{1} \left\{ \begin{array}{ll} i &(i \bmod 4 = 0)\\ 1 &(i \bmod 4 = 1)\\ i + 1 &(i \bmod 4 = 2)\\ 0 &(i \bmod 4 = 3) \end{array} \right. \end{alignat*}
</details>
周期性のある部分の個数を記号に置き換える
たとえば11001100...という1と0からなる数列の、$N$番目までの1の個数を数えるときに、周期性のある部分の個数を$C$とおくことで、1の個数を$C \times 2 + \min((N - C \times 4), 4)$という一つの式で表せます($\min$の部分はAdhocな考察が必要です)。そして$C$についても、$C = \lfloor N / 4 \rfloor$という簡単な計算で求めることができます。
ランレングス圧縮
優先度付きキュー
XORは桁毎に見る
コイン両替問題のDP
dp配列から文字列を復元
最小値(最大値)を保持しながら数列を探索
$O(N!)$全探索
next_permutation()を使って$N!$通りの探索を行います。
二分探索
modの累積和を取る
絶対値は符号を両方試す
1桁目が1の素数を5個足せば合成数になる
$_nC_r$の値は、$n$が大きいほど大きくなり、$r$が$n / 2$に近づくほど大きくなる
ワーシャルフロイド法
ベルマンフォード法
傾き1の直線を傾き0の直線にする
Win-Lose Algorithm
イベントソート
座標圧縮
セグメントツリー
$\sum$の交換、$\sum$の分解
以下の数式を利用することで、計算量を落とせることがあります。 $$\sum_{i=1}^m (a_i + b_i) = \sum_{i=1}^m a_i + \sum_{i=1}^m b_i$$ $$\sum_{i=1}^m \sum_{j=1}^n a_{ij} = \sum_{j=1}^n \sum_{i=1}^m a_{ij}$$ $$\sum_{i=1}^m \sum_{j=1}^n a_ib_j = \sum_{i=1}^m a_i \sum_{j=1}^n b_j $$
約数の個数分だけ全探索
$1 \le N \le 10^9$を満たす$N$の、約数の個数の最大は$1344$個($N = 73513440$)。この少なさを利用して計算量を落とせることがあります。ちなみに、約数の列挙は$O(\sqrt N)$でできます。
next(int i, char c)という関数を定義する
3つのうちの真ん中を固定
2冪の網羅性
$f(x) = |x - a| + b$という形で表せる関数は凸関数
凸関数同士を足すと凸関数になる
数直線上に複数の点があるとき、すべての点との距離の和が最小となる位置は、中央の点の位置
木DP
Trie木
Grundy数
bitDP
木の直径 DFSを2回すれば求まります。
補グラフを考える
$\times 2$と$+ 1$($\times 10$と$+ 1$)
Binary Indexed Tree
転倒数
最小カット
01BFS
変数を減らす
非負整数の最適化問題を、数列の問題に言い換える
$10^9 + 7$で割った余り
貪欲法
Adhocな解法