はじめに
yosupo judge
データ構造やアルゴリズムが沢山集まる場所ですが、どうしてもハードルが高いので、初心者でも取っ掛かりやすいようにまとめます
間違いがあったり追加してほしい記事があればtwitterまで報告してくれると嬉しいです(Qiitaのプルリクでもいいです)
テストケースを見たい方はこちらを参考にしてください
yosupo judgeのテストケースを見る方法
目次
Sample
Data Structure
Graph
Tree
Math
Convolution
Polynomial
Matrix
String
Sample
A + B
Many A + B
fastIO(Codeforces)
高速I/O処理 - yaketake08's 実装メモ
Data Structure
Associative Array
恐らくfixed universe problemの高速処理のverify用?
Trie for Fixed Universe Set -週刊 spaghetti_source
hash tableのverifyな気もしてきた
ハッシュテーブル - wikipedia
Predecessor Problem
恐らく VEBTree 想定です
謎木速いけど微妙にバg・・・バグらないだと!? - 赤い黒歴史を蓄積する
Unionfind
Union-Find木の解説と例題 - Qiita
Union-Findは木じゃない٩(๑`^´๑)۶
Static Range Sum
累積和でもBITでもセグメント木でもなんでもいい
累積和を何も考えずに書けるようにする!
-Qiita
Static RMQ
Sparse Tableを知ったので、忘れないように。 - tookunn's diary
Disjoint Sparse Table と セグ木に関するポエム - noshi91のメモ
構築 O(N) クエリ O(1) の RMQ - noshi91のメモ
前処理O(n)クエリO(1)のLCAと静的RMQ - ジョイジョイジョイ
同じ$<O(N),O(1)>$でもアプローチが違います
Sqrt-tree: answering queries in O(1) with O(NloglogN) preprocessing.(Codeforces)
$<O(N\log \log N),O(1)>$のsparse tableの上位互換です
Point Add Range Sum
セグメント木をソラで書きたいあなたに
セグメント木とかで調べればいくらでも出てきます
Point Set Range Composite
データ構造と代数構造 - koba-e964の日記
セグ木に載せるモノイドまとめ(未完) - beet's soil
要するに可換性を要求しないように注意深くセグメント木を実装しましょうねという話です(非再帰なら要注意)
Range Affine Range Sum
遅延評価セグメント木をソラで書きたいあなたに - hogecoder
Range Chmin Chmax Add Range Sum
Segment Tree Beatsの実装メモ (基本まわり)
Segment Tree Beatsの実装メモ (応用的な例題まわり)
Range Kth Smallest
Vertex Add Path Sum
Easiest HLD with subtree queries(codeforces)
Heavy-Light Decomposition - beet's soil
2種類のEuler Tourについて - beet's soil
オイラーツアーでも解けますがHL分解がおすすめ
Vertex Set Path Composite
同上(向きに気をつけて)(僕はLC木で通しました(後述))
Vertex Add Subtree Sum
同上
Dynamic Tree Vertex Add Path Sum
Link-Cut 木 - ei1333の日記
Link-Cut Treeの実装メモ - 日々drdrする人のメモ
プログラミングコンテストでのデータ構造 2 ~動的木編~
Dynamic Tree Vertex Set Path Composite
同上
Dynamic Tree Vertex Add Subtree Sum
同上+Link Cut Treeで部分木の情報を管理する - beet's soil
Toptree 導入編 - niuez’s diary
Toptree - Link & Cut編 - niuez’s diary
top tree 概要 - noshi91のメモ
TopTreeでも解けます(部分木の情報を管理するLink Cut Tree と TopTree は本質的には同質)
【競技プログラミング】online dynamic connectivity(削除可能union-find)の作り方を詳しく解説!!!
オイラーツアーツリーでも解けます
Dynamic Tree Subtree Add Subtree Sum
同上
Set Xor-Min
非負整数値を扱う Trie について -kazuma8128’s blog
Line Add Get Min
Segment Add Get Min
同上
Queue Operate All Composite
Static Range Frequency
WaveletMatrix で快適な整数列ライフを送ろう
単に集合を管理するデータ構造を用いた平面操作をすることでも解けます。
Static Range Inversions Query
恐らく平方分割より計算量が落ちることはないです
伝家の宝刀 クエリ平方分割について - 思考の墓場
平方分割の練習をしようにも難しい問題ばかり、そんなお悩みに狙いを決めて手取り足取りのレクチャーです! - CADDi ENGENEER Tech Blog
Rectangle Sum
セグメントツリーにセグメントツリーを乗せる手法(2Dセグメントツリー)- はまやんはまやんはまやん
ちょっと変わったセグメント木の使い方 - ei1333の日記
WaveletMatrix で快適な整数列ライフを送ろう
つくってなぐろ (永続配列/永続Union-Find木/永続セグメント木の作り方と意義、具体例)
Point Add Rectangle Sum
セグメントツリーにセグメントツリーを乗せる手法(2Dセグメントツリー)- はまやんはまやんはまやん
Persistent Queue
data-structures - scrapbox
Purely Functional Data Structures(英語)
$O(Q)$があります(よくわからない)
Re永続データ構造が分からない人のためのスライド
ここに出てくる木のダブリングでも出来ます(意外と速いらしいです)
つくってなぐろ (永続配列/永続Union-Find木/永続セグメント木の作り方と意義、具体例)
取り敢えず永続配列持ってれば配列でqueueを作るあれが出来ます
stack2つでqueueを作るやつは償却計算量で抑えられているので普通にやると死にます
Persistent UnionFind
多分部分永続だと無理(だよね?)で全永続UFが必要っぽい
永続配列使ってUFするのが一番ラクそう
部分永続Union-Findの実装 -Mister雑記
つくってなぐろ (永続配列/永続Union-Find木/永続セグメント木の作り方と意義、具体例) -Qiita
Graph
Cycle Detection
DFS (深さ優先探索) 超入門! 〜 グラフ・アルゴリズムの世界への入口 〜【後編】-Qiita
Shortest Path
負辺なしの最短経路はダイクストラ、今回は復元もいるらしい
復元は一般のDPに関する物を貼ったがダイクストラもDPなのでそのまま適用出来る
ダイクストラ法 - ソフトウェア科学研究室
意外と解説がない!動的計画法で得た最適解を「復元」する一般的な方法 -Qiita
Strongly Connected Components
強連結成分分解の意味とアルゴリズム | 高校数学の美しい物語
K-Shortest Walk
Finding the k Shortest Paths (SICOMP'98)-(iwi) 備忘録
Eppstein's Algorithm (Find the K shortest paths) 解説と実装 (Python)-Qiita
K-最短路をO((V+E)logV+KlogK)で!?Eppstein's Algorithmのわかりやすい解説!!!【C++実装つき】-Qiita
自作問題
Two-Edge-Connected Components
橋・二重辺連結成分分解 - あったこといろいろ - id:Yazaten
Three-Edge-Connected Components
わからない(確信がない)です(は?)
作問者しかACしてないので多少はね?
近々解いて書きます(本当ですか?)
A simple 3-edge connected component algorithm revisited
作問者はこれを見て作ったそうです(有料です)(noshi91さんありがとうございます)
Minimum cost b-flow
ぼくの考えたさいきょうのフローライブラリ -
色々ある(作問者のみさわさんの発信を見て作るのが良さそう)
ACするだけならPrimal-Dualでもいいかも(間に合うかは知らない)
Matching on Bipartite Graph
二部グラフの最大マッチングと増加道 | 高校数学の美しい物語
実世界で超頻出!二部マッチング (輸送問題、ネットワークフロー問題)の解法を総整理!
Matching on General Graph
GabowのEdmonds' Algorithm(一般マッチング O(VElogV))の解説と実装
Edge Coloring of Bipartite Graph
二部グラフの辺彩色 - ei1333の日記
シンプルで面白い
Assignment Problem
強烈なテストケースアップデートにより、最小費用流で通すのが難しくなりました。
O(V^3)の特化アルゴリズムである、ハンガリアン法で通すのがおすすめです(逆に速い最小費用流のverifyにも使えます)(僕はcost-scalingで無理やり通しました)
割当問題のハンガリアン法をpythonで実装してみた -Qiita
実世界で超頻出!二部マッチング (輸送問題、ネットワークフロー問題)の解法を総整理!
Directed MST
最小全域有向木(m log n) - ジョイジョイジョイ
最小有向全域木を求める | Chu-Liu/Edmonds' algorithm - Ark's Blog
Manhattan MST
Manhattan Minimum Spanning Tree - 霧でも食ってろ
Dominator Tree
理解を放棄してACだけなら比較的簡単かも(graphのヤバの中では)
Dominator Tree - sigma425のブログ
Maximum Independent Set
素直な高速化をすると通る。非常に教育的な高度典型の一つ。
指数時間アルゴリズム入門 - SlideShare
Chromatic Number
subset convolutionがいると思いきや実は要らない(別に同じ頂点を複数色で塗ってもいいので)
グラフの彩色数求値 $O(2^n n)$ や$O(2^n)を定数倍高速化したもの - Mathenachia
あまりにも賢い解法
Enumerate Triangles
これとてもおもしろい、最大次数√2MのDAGを作って考えるテクは他にも使えそう
Trianguler - SlideShare
Tree Decomposition (width 2)
うしさんがブログに書いた事で少し有名になった概念
グラフを木に変えて木DP出来たりするらしい
本問は連結では無いので、下の手順で森にした後UFやらで適当に繋げる必要がある
うしさんの記事では辺の貼り方がわからないという方にはさてもちブログさんが詳しい
木幅が2以下のグラフの木分解と動的計画法 - ei1333の日記
木分解を眺める: 最小三角化 PEO 計画 - さてもちブログ
Global Minimum Cut of Dynamic Star Augmented Graph
Computing a Minimum Cut in a Graph with Dynamic Edges Incident to a Designated Vertex - researchgate
Minimizing Symmetric Submodular Functions - Slide(Satoru Iwata)
extreme vertex set を求めて木上でHL分解&セグ木 $\mathcal{O}(N^2logN+NM+Q(\log N)^2)$ が想定
最小全域カットを部分問題に含むのでそちらを先に履修するのも手かも
全域最小カット (Stoer-Wagner Algorithm) - 実装メモ (Python)
乱択アルゴリズム紹介(最小カット) - Preferred Networks Resarch & Development
Chordal Graph Recognition
辞書順幅優先探索Lex BFS(Chordal Graph 5回)- kazu0x17’s diary
Chordal Graph: Maximum Cardinality Search - kazu0x17’s diary
グラフ探索アルゴリズムとその応用 - Slide
最初の方に選んだ頂点に隣接する頂点を優先するLexBFSと呼ばれるBFSを使用する
Tree
Tree Diameter
二回DFSするだけの簡単なお仕事
木の直径を求める
Lowest Common Ancestor
Lowest Common Ancestor(yukicoder)
Cartesian Tree
$\lt O(N),O(1)\gt$RMQとかに使えるけど、使いみちは良くわからん(とか言ってたら神記事ができてた)
前処理O(n)クエリO(1)のLCAと静的RMQ - ジョイジョイジョイ
Cartesian tree -wikipedia(en)
列を最小値で分割して再帰するパターンと Cartesian tree
実装法では無いですがいい記事なので
Frequency Table of Tree Distance
重心分解して重心をまたぐ2点に付いてFFTで畳み込む。やりたくないでござる。
ツリーの重心分解 (木の重心分解) の図解 -Qiita
FFT(高速フーリエ変換)を完全に理解する話 -Qiita
Math
Counting Primes
$O(N^{3/4})$とか$O(N^{2/3})$とかで出来るらしい
Meissel-Lehmer algorithmの軽い説明をすると
合成数は$N^{1/3}$以下の素数の倍数と$N^{1/3}$以上$N^{1/2}$以下の素数を2つかけたものの2つなので、両者の集合を$A$,$B$として$\overline{A}$と$\overline{A}\cap B$を頑張って求める
N以下の素数の個数 - メモ
Sum of Multiplicative Function - memo
Meissel–Lehmer algorithm -wikipedia
Enumerate Primes
エラトステネスの篩の高速化(全6章)
Sieve of Eratosthenes Having Linear Time Complexity(英語)
Factorize
素因数分解の高速なアルゴリズム(ロー法) | 高校数学の美しい物語
ミラー–ラビン素数判定法 - Wikipedia
Binomial Coefficient
2015 ICL, Finals, Div. 1 J. Ceizenpok’s formula (nCk mod m の求め方)
nCr mod mの求め方 - uwicoder
lucasの定理で素因数ごとに計算して中国剰余定理で戻す。合成数modの問題は素冪の問題に帰着させることが多い気がする。
Stirling Number of the First Kind
Stirling Number of the Second Kind
同上
Bernoulli Number
Inv of Formal Power Seriesに貼ったやつ+
ベルヌーイ数 - Wikipedia - ウィキペディア
Partition Function
Inv of Formal Power Seriesに貼ったやつ+
分割数 - Wikipedia
オイラーの五角数定理 - Wikipedia
Montmort Number
完全順列 - Wikipedia
漸化式で簡単に解けます
Sum of Totient Function
トーティエント関数の和$\sum_{i=1}^N\phi(i)$を$O(N^{2/3}(loglogN)^(1/3))で求める
トーティエント関数は乗法的関数なので、Dirichlet級数に関するアルゴリズムと捉えることもできます
Dirichlet 積と、数論関数の累積和 - maspyのHP
\sum_{i=0}^{n-1}r^ii^d
Polynomial Sum - memo
AtCoder ARC #033 : D - 見たことのない多項式 - kmjp's blog
TKO919さんの提出(コメントに解法がある)
(恐らく因数定理と言ってるのはヘビサイドのcover-up method?)
\sum_{i=0}^{\infty}r^ii^d
無限和を計算するyosupo judgeの問題 - kyopro_friends’ diary
Eulerian number - Wikipedia(TKO919さんありがとうございます!!)
FFT (NTT) 関連 - memo
Find Linear Recurrence
Berlekamp–Massey algorithm - メモ
多項式を使うテクニックたち(yukicoder)
Kth term of Linearly Recurrent Sequence
Ryuhei Moriさんのblog
線形漸化的数列のN項目の計算 - Qiita
Bostan–Mori のアルゴリズムと呼ばれるアルゴリズムがFiduccia のアルゴリズムよりも高速かつ軽実装であることからよく使用される。Find Linear Recurrenceと合わせて出題される事も多い。
Sum of Floor of Linear
格子点の数え上げの高速化 - memo
Scary Sum - memo
sum of floor of linear の解説するよ - えびちゃんの日記
きちんと考察すれば自力でもいけます
台形内の格子点を求めればいいですが、(x,y)座標の反転を繰り返す事で互除法っぽく三角形領域を切り取っていきます
Sqrt Mod
Tonelli–Shanks algorithm - メモ
整数論テクニック集 - kirika_compのブログ
Kth Root(Mod)
No.981 一般冪乗根 解説 -yukicoder
yukicoderに似たような問題がある
Kth Root(Integer)
二分探索アルゴリズムを一般化 〜めぐる式二分探索法のススメ 〜
C++ (gcc) で 128 ビット整数を使う - 宇宙ツイッタラーXの憂鬱
Discrete Logarithm
「1000000007 で割ったあまり」の求め方を総特集! 〜 逆元から離散対数まで 〜
xとMが互いに素で無い場合が難しいが、$x$と$M/g$が互いに素になるような値$g$を取ってきて
$x^n \equiv y (mod\ g)$かつ$x^n \equiv y (mod\ M)$となるような値を走査する感じでACは出来た
Tetration Mod
Tetration - My Algorithm : kopricky アルゴリズムライブラリ
フェルマーの小定理 - Wikipedia/カーマイケルの定理
$2^k \geq m$の時$a^{n+k} \mod m$は$φ(m)$の約数周期を持つ事を念頭において解きます
koprickyさんのコードは$a=0$のコーナーが抜けてるので注意しましょう(この場合$(b+1)%2%m$を出力) 修正していただきました
Nim Product (\mathbb{F}_{2^{64}})
競プロフレンズさんによるわかりやすい解説がいつの間にか生まれてた!!
通し直そうかな
Nim product - kyopro_friends’ diary
Nimber - Wikipedia
Nim Multiplication - Code Golf Stack Exchange
#_p Subset Sum
部分和問題は$[x^M]\prod_{i=0}^N(1+x^{A_i})$で表せるので
$[x^M]\exp(\sum_{i=0}^Nlog(1+x^{A_i}))$を計算するだけ
A Simple Near-Linear Pseudopolynomial Time
Randomized Algorithm for Subset Sum
2 Sat
2SAT(充足可能性問題)の解き方 - SlideShare
2-SAT のアルゴリズムの証明 - noshi91のメモ
Convolution
Convolution
FFT(高速フーリエ変換)を完全に理解する話
数論変換 (Number Theoretic Transform; NTT) - るまライブラリ
実用にはNTTの方がおすすめですがFFTから作るのがいいと思います
Convolution - Atcoder Library
Atcoder社が用意しているライブラリが存在する
Convolution (mod 1,000,000,007)
[数学・numpy] 高速フーリエ変換(FFT)による畳み込み - maspyのHP
任意modでの畳み込み演算をO(n log(n))で - math314のブログ
Convolution(mod 2^64)
[Convolution (mod 2^64)](Fast convolution for 64-bit integers - Codeforces)
Convolution (Large)
速度計測のために用意されたようである。
Subset Convolution
Andreas Björklund, Thore Husfeldt, Petteri Kaski, and Mikko Koivisto. 2007. Fourier meets möbius: fast subset convolution. In Proceedings of the thirty-ninth annual ACM symposium on Theory of computing (STOC ’07). Association for Computing Machinery, New York, NY, USA, 67–74. / arxiv:
指数時間アルゴリズム入門 - SlideShare
s and t=0∧s or t=kを
s or t=k∧sとtの立ってるビット数の和がkの立ってるビット数に等しい
に言い換えると、多項式をor畳み込みすればOKとわかる
Bitwise And Convolution
Bitwise Xor Convolution
Multivariate Convolution
Multivariate Multiplication - Nyaan's Library
Convolution on the multiplicative monoid of Z / 2^N Z
[問題案] Convolution on the multiplicative monoid of Z/NZ - Github
Polynomial
Inv of Formal Power Series
【競技プログラミング】形式的冪級数の応用テクニック(前編) - Qiita
[多項式・形式的べき級数] 高速に計算できるものたち - maspyのHP
形式的べき級数 - メモ
Operations on Formal Power Series - Codeforces
Exp of Formal Power Series
同上
Log of Formal Power Series
同上
Pow of Formal Power Series
同上、log取ってM倍してexp取るだけだが初項に1が来るように調整が必要だったはず
Sqrt of Formal Power Series
同上
Multipoint Evaluation
Multipoint evaluationの高速実装
因数定理 - Wikipedia
データ構造をマージする一般的なテク - るまぶろぐ-tomorinao
Polynomial Interpolation
Polynomial Taylor Shift
Shift of Sampling Points of Polynomial
[問題案] Shift of Sampling Points - Github
階乗冪 - Wikipedia
標準基底を用いた多項式に戻してから計算すると $\mathcal{O}(N\log^2 N)$ かかってしまうが、下降冪の形に直すことでも二項定理の様な物が成り立つことから Taylor Shift が可能であり、$\mathcal{O}(N\log N)$。
Division of Polynomials
Inv of Formal Power Seriesに貼ったやつ。
形式的ローラン級数 $F_p((x^{-1}))$ の文脈でアルゴリズムを整理する事も出来る。
Inv of Polynomials
多項式GCD - Nyaan's Library
half GCD という手法を利用することで $\mathcal{O}(N \log^2 N)$ で多項式のGCDが出来、これは拡張ユークリッドの互助法と同様の手法でInv of Polynomialsが解ける形に拡張が可能である。
Matrix
Matrix Product
行列の積の定義とその理由 - 高校数学の美しい物語
未確認だが恐らく愚直に計算しても間に合う。
シュトラッセンのアルゴリズム - Wikipedia
シュトラッセンのアルゴリズムよりも計算量のオーダーが小さいアルゴリズムが存在するが、実用的には低速
Determinant of Matrix
行列式の計算 - Tech Tips
Gauss-Jordan の掃き出し法と、連立一次方程式の解き方 - けんちょんの競プロ精進記録
行列式の計算(4) - inamori's diary
Determinant of Sparse Matrix
LU分解+sparse性を利用してbitset高速化するゴリ押しでも解けることには解けます...(非零要素をx,y座標それぞれについてbitsetで持っておく)
LU分解 - [物理のかぎしっぽ]
bitset Find_first and Find_next -codeforces
System of Linear Equations
@hotmanww
— moni (@onakasuita_py) November 11, 2020
Qiitaのyosupo judge全完記事、まだ募集しているかはわからないですが
・Determinant of sparse matrix はこれですhttps://t.co/BlXbdFCl08
・System of linear equations はアルゴリズムという程のものではないですが、Gaussの掃き出しで階段行列に変形して解くものです
Black box linear algebra - yukicoder
これが想定解みたいです(moriさんありがとうございます!!)
Inverse Matrix
Gauss-Jordan の掃き出し法と、連立一次方程式の解き方 - けんちょんの競プロ精進記録
Characteristic Polynomial
ハウスホルダー行列とその性質 - 具体例で学ぶ数学
QR法 - いろはの物置き場
ハウスホルダー変換を用いてヘッセンベルグ行列への相似変換を行い、これを使用して求める。
System of Linear Equations の項に前述したBlack box linear algebraを用いても確率的に解けそうである。 これでは最小多項式しか求められず、嘘の可能性が高いです。申し訳ありません。(10/08 09:01 追記)
Hafnian of Matrix
定義は簡単だけど求めるのは大変...偶奇だけなら簡単です(行列式と一致します)
行列のパフィアン,パーマネント,ハフニアン - 高校数学の美しい物語
Björklund, A. (2012, January). Counting perfect matchings as fast as Ryser. In Proceedings of the twenty-third annual ACM-SIAM symposium on Discrete Algorithms (pp. 914-921). Society for Industrial and Applied Mathematics.
ハフニアン(無向グラフの完全マッチングの個数)
String
Z Algorithm
【図解】線形時間の文字列アルゴリズム「Z algorithm」をイラストとアニメーションでかみ砕く
Enumerate Palindromes
文字列の頭良い感じの線形アルゴリズムたち2 - あなたは嘘つきですかと聞かれたら「YES」と答えるブログ
Suffix Array
Suffix ArrayのO(NlogN)構築(とおまけでSA-IS) - 足跡-sokuseki-
Number of Substrings
I - Number of Substrings - Atcoder
Suffix Array+LCPで解けます
Suffix Automatonの作り方と使い方 - uwicoder
Suffix Automatonでも解けます
Run Enumerate
Runの列挙 (Main-Lorentz algorithm) - 迷いませんか?
これわかりやすいです
Suffix Automatonでも解けるらしいです
Geometry
Sort Points by Argument
C++で点を偏角ソートをしたい(反時計にソートしたい)【軽実装編】
上下に分けて外積(というより傾きの式の式変形)やる方が良いと思います
Convex Layers
Dynamic convex hull implementation - Codeforces
decremental convex hull を処理できるデータ構造を使用して、「convex hullを求める」、「convex hullに含まれる頂点を削除する」を交互に繰り返します。