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な解法 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★