前言


杂项

快读快写

巨佬模板


玄学优化|卡常

吸氧,吸臭氧

正则表达式

随机数


哈希

双哈希,好多哈希,题目链接


计算log2

快速开根号|牛顿迭代法

i/k == j 的 k 的个数

三分法

示例为凹函数

三维偏序|CDQ分治

四维偏序

CDQ套CDQ

第一维在第一层CDQ合并时标记左右区间

合并后第二维有序,进入第二层CDQ

此时按照正常CDQ合并第三维,用数据结构统计第四维

只有标记左区间的加入数据结构,标记右边区间的更新答案

某区间操作问题

每次操作可以使一个区间+1(或-1),使得序列为0的操作次数下界 $\frac{\sum\limits_{i=1}^{n+1}\lvert a_i-a_{i-1} \rvert}{2}$

分数规划

分数规划用来求一个分式的极值。

形象一点就是,给出 $a_i$ 和 $b_i$,求一组 $w_i\in{0,1}$,最小化或最大化

$$ \displaystyle\frac{\sum\limits_{i=1}^na_i\times w_i}{\sum\limits_{i=1}^nb_i\times w_i} $$

每种物品有两个权值 $a$ 和 $b$,选出若干个物品使得 $\displaystyle\frac{\sum a}{\sum b}$ 最小/最大。

例如代价为 平均值 或 乘积开个数次根(取ln)

分数规划问题的通用方法是二分。

假设我们要求最大值。二分一个答案 $mid$,然后推式子(为了方便少写了上下界):

$$\displaystyle
\begin{aligned}
&\frac{\sum a_i\times w_i}{\sum b_i\times w_i}>mid\
\Longrightarrow&\sum a_i\times w_i-mid\times \sum b_i\cdot w_i>0\
\Longrightarrow&\sum w_i\times(a_i-mid\times b_i)>0 \end{aligned}$$

那么只要求出不等号左边的式子的最大值就行了。如果最大值比 $0$ 要大,说明 $mid$ 是可行的,否则不可行。

不转义

R”()”

十六进制输出内存

两两组合

2n 个人两两组合方案数 $(2n-1)(2n-3)\dots$

INF

高维前缀和

可以将高维数组映射成一维,从小到大枚举即可


计算几何

向量 坐标 直线 圆 (结构体)


二维凸包


平面最近点对


最小圆覆盖|随即增量法


数据结构

可删堆

copyright by axiomofchoice

二叉查找树

平衡树

替罪羊树|Scapegoat Tree

Treap

Splay

区间反转

线段树

区间加减区间和

区间修改区间和

区间加减区间最值

区间更新最值

区间最大连续子段和

ZKW线段树

warning:区间最值尚为验证

李超线段树

李超线段树是一种用于维护平面直角坐标系内线段关系的数据结构。它常被用来处理这样一种形式的问题:给定一个平面直角坐标系,支持动态插入一条线段,询问从某一个位置 (x,+∞) 向下看能看到的最高的一条线段(也就是给一条竖线,问这条竖线与所有线段的最高的交点。

线段树合并

有 $O(m)$ 棵树(个操作) 结点数量 $O(m\log n)$, 暴力合并,均摊复杂度 $O(\log n)$

线段树分裂

一次分裂复杂度 $O(\log n)$

猫树

所谓 “猫树” 就是一种不支持修改,仅仅支持快速区间询问的一种静态线段树。

构造一棵这样的静态线段树需要 $O(n\log n)$ 次合并操作,但是此时的查询复杂度被加速至 $O(1)$ 次合并操作。

吉老师线段树|吉司机线段树

区间最值操作

  1. 区间取min
  2. 询问区间min
  3. 询问区间和

$O(m \log n)$

  1. 给一个区间[L,R] 加上一个数x
  2. 把一个区间[L,R] 里小于x 的数变成x
  3. 把一个区间[L,R] 里大于x 的数变成x
  4. 求区间[L,R] 的和
  5. 求区间[L,R] 的最大值
  6. 求区间[L,R] 的最小值

$O(m\log^2 n)$

区间历史最值

区间加区间修改

  1. 区间加
  2. 区间修改
  3. 区间最大值
  4. 区间历史最大值

$O(m\log n)$

区间最值操作与历史最值询问同向

单点查询

区间最值操作与历史最值询问反向

  1. 区间加
  2. 区间max
  3. 询问min
  4. 历史min

维护历史最值和

树套树

在第一维线段树的每个结点建立第二维线段树

K-D Tree | KDT

Luogu P4148 简单题

  1. 将格子(x,y)加上v
  2. 求(xl,yl)到(xr,yr)区间和

树状数组

一维

单点修改区间查询

区间修改单点查询

O(n)初始化


区间修改区间查询

二维

单点修改区间查询

可持久化数组

可持久化线段树(主席树)

自带离散

不带离散

动态开点?oj可以跑本地莫名re

dingbacode 高地

分块

例题



莫队

$O(1)修改$ 一般取 $block = \frac{n}{\sqrt{m} }, O(n\sqrt{m})$

移动前两步先扩大区间 $l–,r++$ 后两步缩小区间 $l++,r–$

奇偶性排序

带修改莫队

以 $n^{\frac{2}{3} }$ 为一块,分成了 $n^{\frac{1}{3} }$ 块,第一关键字是左端点所在块,第二关键字是右端点所在块,第三关键字是时间. 复杂度 $O(n^{\frac{5}{3} })$

值域分块

维护块的前缀和以及块内部前缀和, $O(\sqrt{n})$ 修改, $O(1)$ 求区间和

二次离线莫队

大概是一种需要维护信息具有可减性的莫队。只要具可减性,就可以容斥,就可以二次离线。所谓『二次离线』,大概是指由于普通莫队无法快速计算贡献,所以第一次离线把询问离线下来,第二次离线把莫队的转移过程离线下来。

由于信息具有可减性(比如常见的「点对数」),记 $(a,b)(c,d)$ 表示区间 $[a,b]$ 内的点和区间 $[c,d]$ 内的点对彼此产生的贡献(区间内部不算)。

$[l,r]\to[l+t,r],\sum\limits_{i=l}^{l+t−1}(i,i)(i+1,r)=\sum\limits_{i=l}^{l+t−1}(i,i)(1,r)−(i,i)(1,i)$

$[l,r]\to[l-t,r],\sum\limits_{i=l-t}^{l-1}(i,i)(i+1,r)=\sum\limits_{i=l-t}^{l-1}(i,i)(1,r)−(i,i)(1,i)$

$[l,r]\to[l,r+t],\sum\limits_{i=r+1}^{r+t}(i,i)(l,i-1)=\sum\limits_{i=r+1}^{r+t}(1,i-1)(i,i)-(1,l-1)(i,i)$

$[l,r]\to[l,r-t],\sum\limits_{i=r-t+1}^{r}(i,i)(l,i-1)=\sum\limits_{i=r-t+1}^{r}(1,i-1)(i,i)-(1,l-1)(i,i)$

对于 $(1,i-1)(i,i)$ 没什么好说,暴力处理前缀和

对于 $(1,l-1)(i,i)$ 由于莫队的复杂度,至多有 $n\sqrt{m}$ 个不同询问,把每个询问 打标记到左端点(比如 $[l,r]\to [l,r-t]$ 就打到 $l-1$ 上), 最后扫一遍全部 $i \in [1,n]$ ,处理出询问值, 因为此时 $i$ 枚举 $O(n)$ 次,可以用『值域分块』技巧。这样最终复杂度 $O(n\sqrt n+n\sqrt{n})$

求区间逆序对

ST表

一维

二维

$O(nm\log n \log m)$

反向ST


并查集

路径压缩

按秩合并

秩的意思就是树的高度,按秩合并过后并查集的结构为树形结构,最坏情况为 $O(m \log n)$

启发式合并

带权并查集

扩展域并查集

例题:关押罪犯,食物链

可撤销并查集

用一个栈维护每次操作

按秩合并

启发式合并

可撤销扩展域并查集

可持久化并查集


单调队列

左偏树|可并堆

1 x y:将第 x 个数和第 y 个数所在的小根堆合并(若第 x 或第 y 个数已经被删除或第 x 和第 y 个数在用一个堆内,则无视此操作)。

2 x:输出第 x 个数所在的堆最小数,并将这个最小数删除(若有多个最小数,优先删除先输入的;若第 x 个数已经被删除,则输出 -1 并无视删除操作)。


字符串

回文字符串|manacher算法

从 0 开始,第 i 位对应 p[i*2+2]

判断s[l, r]是否为回文


KMP

.c_str() 未知异常 Segment Fault


nex 数组往上跳为公差为 i-nex[i] 的等差数列直到 i/2

扩展KMP|Z函数

最长公共前后缀

hdu2594

Hash


BM算法

Sunday算法

字符串哈希


字典树

求异或

最大异或


动态开点+支持合并

AC自动机

AC 自动机是 以 Trie 的结构为基础,结合 KMP 的思想 建立的。

将所有模式串构成一棵 Trie, 再对所有结点构造失配指针

Luogu P3808
如需构造可重建AC自动机,每次构造建一个nex数组的拷贝

Luogu P5357

后缀数组|SA

$sa[i]$ 表示将所有后缀排序后第 $i$ 小的后缀的编号

$rk[i]$ 表示后缀 $i$ 的排名

性质:$sa[rk[i]]=rk[sa[i]]=i$

$lcp(i, j)$ 表示后缀 $i$ 和后缀 $j$ 的最长公共前缀(的长度)

$height[i]=lcp(sa[i], sa[i-1])$

引理 $height[rk[i]] \geq height[rk[i-1]]-1$

$lcp(sa[i],sa[j])=\min{height[i+1\cdots j]}$

不同子串数目:$\frac{n(n+1)}{2}-\sum\limits_{i=2}^{n}{height[i]}$

$O(nlog^2n)$

$O(nlogn)$

$O(n)$

树上SA

树上可能出现完全相同的字符串,增加上一轮的有序状态rk为”第三关键字”

后缀平衡树

后缀自动机|SAM

一个状态表示一个 $endpos$ 的等价类

$len(v)$ 为该状态最长的字符串长度

后缀链接 $link(v)$ 连接到对应于该状态最长字符串的最长后缀的另一个 $endpos$ 等价类的状态。

代码

空间换时间


时间换空间

检查字符串是否出现

丢进去转移。这个算法还找到了模式串在文本串中出现的最大前缀长度。

不同子串个数

不同子串的个数等于自动机中以 $t_0$ 为起点的不同路径的条数-1(空串)。令 $d_{v}$ 为从状态 $v$ 开始的路径数量(包括长度为零的路径)

$d_{v}=1+\sum\limits_{w:(v,w,c)\in DAWG}d_{w}$

另一种方法是利用上述后缀自动机的树形结构。统计节点对应的子串数量 $\operatorname{len}(i)-\operatorname{len}(\operatorname{link}(i))$

ps:若新增一个字符,其增量为$len(cur)-len(link(cur))$ 不包括 $clone$ 结点

所有不同子串的总长度

$ans_{v}=\sum\limits_{w:(v,w,c)\in DAWG}d_{w}+ans_{w}$

法二:每个节点对应的所有后缀长度是 $\frac{\operatorname{len}(i)\times (\operatorname{len}(i)+1)}{2}$,减去其 $\operatorname{link}$ 节点的对应值就是该节点的净贡献

字典序第 k 大子串

不同位置的相同子串算作一个,每个非 clone 状态的数量记为1

不同位置的相同子串算作多个,每个状态的数量为 parent 树上求子树和

在 SAM 的 DAG 求和然后字典序搞搞

两个字符串的最长公共子串

多个字符串间的最长公共子串

记录 $f[i][j]$ 为第 $i$ 个字符串在 sam 上状态 $j$ 的匹配长度

$ans = \max\limits_{j}{(\min\limits_{i}{f[i][j]})}$

后缀的最长公共前缀|height

求两个后缀的最长公共前缀,显然就是两个后缀的节点在Parent树上的LCA

广义后缀自动机

广义后缀自动机 (General Suffix Automaton) 是将后缀自动机整合到字典树中来解决对于多个字符串的子串问题

离线构造

在线构造

多个字符串间的最长公共子串

设有 $k$ 个字符串,每个结点建立长度为 $k$ 的标记,在 parent 树自底向上合并,若满足所有标记,则记录

(对于本题而言,可以仅为标记数组,若需要求出此子串的个数,则需要改成计数数组)(可用二进制或bitset)

根号暴力

在 parent 树上从字符串的每一个前缀的状态暴力往上跳(须标记vis)

例如可用此法记录上述的标记数组

证明:对于第 $i$ 个字符串,它最多会贡献 $\min{(n,\lvert s_i \rvert^2)}, n=\sum{\lvert s_i \rvert},O(n\sqrt{n})$

树上本质不同路径数

一颗无根树上任意一条路径必定可以在以某个叶节点为根时,变成一条从上到下的路径

暴力把所有叶子结点为根的树加入自动机,就这?

循环同构问题

CF235C:SAM 读入字符串是支持删除首字符的! 将一个字符串所有的循环同构串插入到 sam, 外加 vis 去重

最小表示法

$S[i\cdots n]+S[1\cdots i-1] = T$ 则称 $S$ 与 $T$ 循环同构

字符串 $S$ 的最小表示为与 $S$ 循环同构的所有字符串中字典序最小的字符串

$O(n)$

Lyndon分解

Lyndon 串:对于字符串 $s$,如果 $s$ 的字典序严格小于 $s$ 的所有后缀的字典序,我们称 $s$ 是简单串,或者 Lyndon 串。

Lyndon 分解:串 $s$ 的 Lyndon 分解记为 $s=w_1w_2\cdots w_k$,其中所有 $w_i$ 为简单串,并且他们的字典序按照非严格单减排序,即 $w_1\ge w_2\ge\cdots\ge w_k$。可以发现,这样的分解存在且唯一。

Duval 可以在 $O(n)$ 的时间内求出一个串的 Lyndon 分解。


回文树|回文自动机|PAM

定理:对于一个字符串 $s$,它的本质不同回文子串个数最多只有 $\lvert s \rvert$ 个。

状态数,复杂度 $O(n)$

由于回文树的构造过程中,节点本身就是按照拓扑序插入,因此可以按序枚举所有状态实现树遍历

特殊log性质

记字符串 $s$ 长度为 $i$ 的前缀为 $pre(s,i)$,长度为 $i$ 的后缀为 $suf(s,i)$

周期:若 $0< p \le |s|$,$\forall 1 \le i \le |s|-p,s[i]=s[i+p]$,就称 $p$ 是 $s$ 的周期。

border:若 $0 \le r < |s|$,$pre(s,r)=suf(s,r)$,就称 $pre(s,r)$ 是 $s$ 的 border。

周期和 border 的关系:$t$ 是 $s$ 的 border,当且仅当 $|s|-|t|$ 是 $s$ 的周期。

引理 $1$:$t$ 是回文串 $s$ 的后缀,$t$ 是 $s$ 的 border 当且仅当 $t$ 是回文串。

引理 $2$:$t$ 是回文串 $s$ 的 border ($|s|\le 2|t|$),$s$ 是回文串当且仅当 $t$ 是回文串。

引理 $3$:$t$ 是回文串 $s$ 的 border,则 $|s|-|t|$ 是 $s$ 的周期,$|s|-|t|$ 为 $s$ 的最小周期,当且仅当 $t$ 是 $s$ 的最长回文真后缀。

引理 $4$:$x$ 是一个回文串,$y$ 是 $x$ 的最长回文真后缀,$z$ 是 $y$ 的最长回文真后缀。令 $u,v$ 分别为满足 $x=uy,y=vz$ 的字符串,则有下面三条性质

$|u| \ge |v|$;

如果 $|u| > |v|$,那么 $|u| > |z|$;

如果 $|u| = |v|$,那么 $u=v$。

推论:$s$ 的所有回文后缀按照长度排序后,可以划分成 $\log |s|$ 段等差数列。

回文树上的每个节点 $u$ 需要多维护两个信息,$diff[u]$ 和 $slink[u]$。$diff[u]$ 表示节点 $u$ 和 $fail[u]$ 所代表的回文串的长度差,即 $len[u]-len[fail[u]]$。$slink[u]$ 表示 $u$ 一直沿着 fail 向上跳到第一个节点 $v$,使得 $diff[v] \neq diff[u]$,也就是 $u$ 所在等差数列中长度最小的那个节点。

      diff[x] = len[x]-len[fail[x]];
      slink[x] = diff[x] == diff[fail[x]] ? slink[fail[x]] : fail[x];
for (int i = 2; i <= sz; ++i)
  for (int j = i, k = slink[i]; j; j = k, k = slink[j])
    // 等差数列[len[k], len[j]] d = diff[j]

最小回文划分

问题描述:求最小的 $k$,使得字符串能分成 $k$ 段且每段都是回文串

暴力:$dp[i]=1+\min\limits_{s[j+1\cdots i]为回文串}dp[j]$

$g[v]$ 表示 $v$ 所在等差数列的 $dp$ 值之和,且 $v$ 是这个等差数列中长度最长的节点,则 $g[v]=\sum_{x,slink[x]=v} dp[i-len[x]]$,这里 $i$ 是当前枚举到的下标。(该题改求和为取min)

假设当前枚举到第 $i$ 个字符,回文树上对应节点为 $x$。$g[x]=g[fail[x]]+dp[i-(len[slink[x]]+diff[x])]$

回文级数优化回文树上dp

问题描述:把字符串 $s$ 划分成若干个字符串 $t_1t_2\cdots t_k$,使得 $t_i=t_{k-i+1}$,求方案数

问题转化:将字符串转为 $s_1s_ns_2s_{n-1}\cdots$,原划分方案恰好对应了对新串进行偶数长度的回文划分的方案

tips:只需要考虑偶数下标位置的 $dp$ 值即可

序列自动机

序列自动机是接受且仅接受一个字符串的子序列的自动机。

Main-Lorentz 算法

我们将一个字符串连续写两遍所产生的新字符串称为 重串 (tandem repetition)。将被重复的这个字符串称为原串。

如果一个重串的原串不是重串,则我们称这个重串为 本原重串 (primitive repetition)。可以证明,本原重串最多有 $O(n \log n)$ 个。

如果我们把一个重串用 Crochemore 三元组 $(i, p, r)$ 进行压缩,其中 $i$ 是重串的起始位置,$p$ 是该重串某个循环节的长度(注意不是原串长度!),$r$ 为这个循环节重复的次数。则某字符串的所有重串可以被 $O(n \log n)$ 个 Crochemore 三元组表示。

图论|树论

DFS树

树的重心

最大团

最大独立集数=补图的最大团


稳定婚姻匹配


最小生成树

Prim


Kruskal (略)


二分图

二分图最大匹配

增广路算法 Augmenting Path Algorithm $O(nm)$


网络流 $O(\sqrt{n}m)$

二分图最大权匹配

Hungarian Algorithm (Kuhn-Munkres Algorithm)
匈牙利算法又称为 KM 算法,可以在 $O(n^3)$ 时间内求出二分图的 最大权完美匹配。

二分图最小顶点覆盖

定义:假如选了一个点就相当于覆盖了以它为端点的所有边。最小顶点覆盖就是选择最少的点来覆盖所有的边。

定理:最小顶点覆盖等于二分图的最大匹配。

最大独立集

定义:选出一些顶点使得这些顶点两两不相邻,则这些点构成的集合称为独立集。找出一个包含顶点数最多的独立集称为最大独立集。

定理:最大独立集 = 所有顶点数 - 最小顶点覆盖 = 所有顶点数 - 最大匹配


最近公共祖先|LCA

倍增

树剖

欧拉序

dfs 时进入一个节点加入序列,回溯回来也加一次

lca 转变为区间深度最小的点

带权LCA

最小环


树上差分

树链剖分


网络流

网络流24题

最大流

EK

$O(nm^2)$

Dinic

普通情况下 $O(n^2m)$
二分图中 $O(\sqrt{n}m)$

该板子存在可能效率极其低下的问题

ISAP

渐进时间复杂度和dinic相同,但是非二分图的情况下isap更具优势
在某些情况(题目)中远慢于dinic

OI Wiki版本

Luogu版本

HLPP

最小割

最小割等价最大流

费用流

MCMF

类Dinic

Dijkstra

Primal-Dual 原始对偶算法

ZKW_SPFA

上下界网络流

全局最小割StoerWagner


最短路

弱化
标准

Floyd

Dijkstra

邻接表+堆优化

SPFA


负环


割点


SCC强连通分量|Tarjan

递归版本

非递归版本

缩点

2-SAT

SCC Tarjan

$O(n+m)$

DFS

$O(nm)$
所求结果字典序最小

虚树

线段树优化建图

+最短路

+网络流

+2-SAT

矩阵树定理|Kirchhoff

解决一张图的生成树个数计数问题(详情见oi-wiki)

斯坦纳树

给定连通图 $G$ 中的 $n$ 个点 $m$ 条边与 $k$ 个关键点,连接 $k$ 个关键点,使得生成树的所有边的权值和最小。

我们使用状态压缩动态规划来求解。用 $f(i,S)$ 表示以 $i$ 为根的一棵树,包含集合 $S$ 中所有点的最小边权值和。

边权最小

  • 首先对连通的子集进行转移, $f(i,S)\leftarrow \min(f(i,S),f(i,T)+f(i,S-T))$ 。

  • 在当前的子集连通状态下进行边的松弛操作, $f(i,S)\leftarrow \min(f(i,S),f(j,S)+w(j,i))$

复杂度 $O(n\times 3^k+m\log m\times 2^k)$

点权最小

  • $f(i,S)\leftarrow \min(f(i,S),f(i,T)+f(i,S-T)-a_i)$ 。由于此处合并时同一个点 $a_i$ ,会被加两次,所以减去。

  • $f(i,S)\leftarrow \min(f(i,S),f(j,S)+w(j,i))$ 。

路径输出

树上背包

时间复杂度 $O(n^2)$

仙人掌

两点之间最短路

仙人掌DP

补图DFS

浅谈图模型上的随机游走问题

网格图

$$f(i)=
\begin{cases}
p_1f(i-1,j)+p_2f(i,j-1)+p_3f(i+1,j)+p_4f(i,j+1)+1,i^2+j^2\leq R \\
0,i^2+j^2<R
\end{cases}$$

高斯消元 $O(R^6)$

直接消元法 $O(R^4)$

主元法 $O(R^3)$

树分治

点分治

按树的重心分治

边分治

欧拉图

Hierholzer 算法

复杂度 $O(n+m)$

保存答案可以使用 stack ,因为如果找的不是回路的话必须将那一部分放在最后。

如 E{(1,2),(2,3),(3,4),(4,5),(5,3)}


数论

快排


求第K大数

HDOJ 2665
POJ 2104


STL (排序,无返回值)

bfprt 算法

目前解决TOP-K问题最有效的算法即是BFPRT算法,又称为中位数的中位数算法,最坏时间复杂度为O(n)。


求逆序对(归并排序)


线性基

求最大值Luogu3812

求第k大数HDOJ3949


前缀和线性基
vector跑贼鸡儿慢


矩阵

矩阵快速幂

矩阵求逆

高斯消元

异或方程组

luogu 2962

a[i][j] 第i个是否对j有影响

a[i][n+1] 第i个最后被翻转与否


拉格朗日插值


快速幂


快速乘


复数


快速傅里叶变换|FFT


快速数论变换|NTT

任意模数NTT|MTT

分治FFT

快速沃尔什变换|FWT

推导详解

公式参考

洛谷例题

复杂度 $O(n\log n) | O(n2^n)$

$FWT(A\pm B)=FWT(A)\pm FWT(B)$

$FWT(cA)=cFWT(A)$

定义 $\bigoplus$ 为任意集合运算

$FWT(A\bigoplus B)=FWT(A)\times FWT(B)$

求 $C_i = \sum\limits_{i=j\bigoplus k}{a_j b_k}$

或运算

$FWT(A)[i] = \sum\limits_{j|i=i}{A[j]}$

$FWT(A) = [FWT(A_0),FWT(A_0+A_1)]$

$IFWT(A) = [IFWT(A_0),IFWT(A_1)-IFWT(A_0)]$

与运算

$FWT(A)[i] = \sum\limits_{i\&j=j}{A[j]}$

$FWT(A) = [FWT(A_0+A_1),FWT(A_1)]$

$IFWT(A) = [IFWT(A_0)-IFWT(A_1),IFWT(A_1)]$

异或运算

令 $d(x)$ 为 $x$ 在二进制下拥有的1的数量

$FWT(A)[i] = \sum\limits_{j}(-1)^{d(i\&j)}A[j]$

$FWT(A) = [FWT(A_0+A_1),FWT(A_0-A_1)]$

$IFWT(A) = [\frac{IFWT(A_1-A_0)}{2},\frac{IFWT(A_1+A_0)}{2}]$

code

快速莫比乌斯变换|FMT

据说 FWT 做的事情完全包含 FMT 且常数是一半(咕之

快速子集变换(子集卷积)|FST

$C_k = \sum\limits_{i\&j=0,i|j=k}{A_i B_j}$

复杂度 $O(n\log^2 n) | O(n^22^n)$

分治FWT

形同分治FFT

倍增子集卷积

hdu6851

设多项式 $A = \sum\limits_{i=0}^{2^n-1}{a_i x^i},B=\sum\limits_{i=0}^{2^n-1}{b_i x^i}$

求 $C = A*B = \sum\limits_{i=0}^{2^n-1}{x^i \sum\limits_{d\subseteq i}{a_d b_{i-d} }}$

按照每个状态的最高位进行分组,然后卷 $n$ 次

复杂度 $O(\sum\limits_{i=1}^{n}{i^2 2^i}) = O(n^2 2^n)$


第二类斯特林数


约瑟夫环

O(n)


最大公因数 gcd

最小公倍数 lcm

$LCM(\frac{a}{b},\frac{c}{d})=\frac{LCM(a, c)}{GCD(b,d)}$

$LCM(\frac{a_1}{b_1},\frac{a_2}{b_2},…)=\frac{LCM(a1, a2,…)}{GCD(b1, b2,…)}$

扩展欧几里得(同余方程)


乘法逆元

拓展欧几里得

费马小定理

线性递推


中国剩余定理

中国剩余定理CRT(m互质)

扩展中国剩余定理EXCRT(m不互质)


排列组合

奇偶性

C(n,k) 当 n&k == k 为奇数反之偶数


欧拉函数

筛法

欧拉定理

a 与 m 互质时,$a^{\phi(m)} \equiv 1 \mod m$

扩展欧拉定理

无需 a,m 互质 $b > \phi(m),a^b \equiv a^{(b \mod \phi(m))+\phi(m)} \mod m$

莫比乌斯函数


线性筛素数

求所有因子

判断素数(质数)

某较优方法

Miller-Rabin 素性测试

线性筛GCD


分解质因数


BSGS

求解关于 $t$ 的方程 $a^t \equiv x(mod m),\gcd(a, m) = 1$

拓展BSGS

$\gcd(a, m) \neq 1$

错排

$D_1 = 0$

$D_2 = 1$

$D_n = (n-1)(D_{n-1}+D_{n-2})$

原根

参考博客

复杂度 $O(\sqrt{m}+g\times\log^2m)$

单位根反演

$[k|n]=\frac{1}{k}\sum\limits_{i=0}^{k-1}w_{k}^{ni}$

$[a\equiv b(\mod n)]=[a-b \equiv 0(\mod n)]=\frac{1}{n}\sum\limits_{i=0}^{n-1}w_n^{(a-b)k}=\frac{1}{n}\sum\limits_{i=0}^{n-1}w_n^{ak}w_n^{-bk}$

单位根卷积

$\sum\limits_{i=0}^{n}[i\%k=0]f(i)=\sum\limits_{i=0}^{n}\frac{1}{k}\sum\limits_{j=0}^{k-1}(w_k^i)^jf(i)$

大数阶乘

分块打表

全排列和逆序对

根据逆序数推排列数

已知一个n元排列的逆序数为m,这样的n元排列有多少种?

  1. 对任意n>=2且0<=m<=C(n,2)时f(n,m)>=1;当m>C(n,2)时,f(n,m)=0
  2. f(n,m)=f(n,C(n,2)-m)
  3. f(n+1,m)=f(n,m)+f(n,m-1)+…+f(n,m-n)
  4. f(n,0)=f(n,C(n,2))=1
  5. f(n,1)=f(n,C(n,2)-1)=n-1(n>1)
  6. f(n,2)=f(n,C(n,2)-2)=C(n,2)-1(n>2)

根据每个数的逆序数求出原排列

根据逆序数求最小排列

  1. 对于n的全排列,在它完全倒序的时候(也就是n,n-1,…,2,1的时候)逆序数最多。
  2. 对于一个形如1,2,3,…,i-1,i,n,…i+1的排列q(如n=5时的1,2,5,4,3),即在数n前保证首项为1且严格以公差为1递增而数n之后排列任意的数列
    • 当数n之后是递减的时候q的逆序数最多,为t=C(n-i,2)。
    • 排列q是出现逆序数为t的最小排列。
  3. 在上一条所设定的排列q的基础上,我们将数n后面的第k小数与数n的前一个数(即i)交换,然后使数n后面保持逆序。这样得到的新排列所含的逆序数为t=C(n-i,2)+k,且这个排列是逆序数为t的最小排列。

    第k个字典序每个数的逆序对

二次剩余


动态规划 DP

(我全都不会)

记忆化搜索

线性DP

最长上升子序列LIS

最长公共子序列LCS

数字三角形

区间DP

树形DP

状压DP

枚举子集

枚举n个元素,大小为k的二进制子集

背包问题

01背包

完全背包

混合背包

分组背包

多重背包

二进制拆分


单调队列


SOS DP

WQS二分|DP凸优化

题目给了一个选物品的限制条件,要求刚好选m个,让你最大化(最小化)权值, 其特点是函数的斜率单调

例:给你一个N个点M条边无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有K条白色边的生成树。

记 $g(i)$ 是选了 $i$ 条白边的最小生成树值, 发现 $g(i)$ 斜率单调不增 $g(i)-g(i-1) \leq g(i+1)-g(i)$

则二分斜率 k, 求切点(截距最大)

设$f(x)$为我在没有固定选多少个点(但是我已经选了x个点)时的答案(也就是截距), $f(x)=g(x)-k*x$

只要把每个数的$h(x)−=k$然后正常求一下在选任意个数的情况下最大$f(x)$是多少 $O(n\log n)$

斜率优化

若dp方程为 $dp[i]=a[i] \cdot b[j]+c[i]+d[j]$ 时,由于存在$a[i] \cdot b[j]$ 这个既有 $i$ 又有 $j$ 的项,就需要使用斜率优化

「HNOI2008」玩具装箱 TOY

$dp[i]=min(dp[j]+(sum[i]+i−sum[j]−j−L−1)^2)(j<i)$

令$a[i]=sum[i]+i,b[i]=sum[i]+i+L+1$

$dp[i]=dp[j]+(a[i]-b[j])^2$

$dp [ i ] = dp [ j ] + a [ i ] ^ 2 - 2 a [ i ] b [ j ] + b [ j ] ^ 2$

$2 a [ i ] b [ j ] + dp [ i ] - a [ i ] ^ 2 = dp [ j ] + b [ j ] ^ 2$

将 $b[j]$ 看作 $x,dp[j]+b[j]^2$ 看作 $y$,这个式子就可以看作一条斜率为 $2 a[i]$ 的直线

而对于每个 $i$ 来说, $a[i]$ 都是确定的, 类似线性规划

$dp[i]$ 的含义转化为:当上述直线过点 $P(b[j],dp[j]+b[j]^2)$ 时,直线在 $y$ 轴的截距加上 $a[i]^2$ (一个定值) 而题目即为找这个截距的最小值

四边形不等式

2D1D

$f_{l,r}=\min\limits_{k=l}^{r-1} {f_{l,k}+f_{k+1,r}}+w(l,r) \ \ (1\leq l \leq r \leq n)$

当 $w(l,r)$ 满足特定性质

  • 区间包含单调性 :如果对于任意 $l\leq l’ \leq r’ \leq r$ ,均有 $w(l’,r’)\leq w(l,r)$ 成立,则称函数 $w$ 对于区间包含关系具有单调性。

  • 四边形不等式 :如果对于任意 $l_1 \leq l_2 \leq r_1 \leq r_2$ ,均有 $w(l_1,r_1)+w(l_2,r_2) \leq w(l_1,r_2)+w(l_2,r_1)$ 成立,则称函数 $w$ 满足四边形不等式(简记为“交叉小于包含”)。若等号永远成立,则称函数 $w$ 满足 四边形恒等式 。

引理 1 :若满足关于区间包含的单调性的函数 $w(l,r)$ 满足四边形不等式,则状态 $f_{l,r}$ 也满足四边形不等式。

定理 1 :若状态 $f$ 满足四边形不等式,记 $m_{l,r}=\min{k:f_{l,r}=g_{k,l,r}}$ 表示最优决策点,则有 $m_{l,r-1} \leq m_{l,r} \leq m_{l+1,r}$

1D1D

$f_r = \min\limits_{l=1}^{r-1} {f_l+w(l,r)} \ \ (1\leq r \leq n)$

定理 2 :若函数 $w(l,r)$ 满足四边形不等式,记 $h_{l,r}=f_l+w(l,r)$ 表示从 $l$ 转移过来的状态 $r$ , $k_r=\min{l|f_r=h_{l,r}}$ 表示最优决策点,则有 $\forall r_1 \leq r_2 : k_{r1} \leq k_{r2}$

满足四边形不等式的函数类

  • 性质 1 :若函数 $w_1(l,r),w_2(l,r)$ 均满足四边形不等式(或区间包含单调性),则对于任意 $c_1,c_2\geq 0$ ,函数 $c_1w_1+c_2w_2$ 也满足四边形不等式(或区间包含单调性)。

  • 性质 2 :若存在函数 $f(x),g(x)$ 使得 $w(l,r) = f(r)-g(l)$ ,则函数 $w$ 满足四边形恒等式。当函数 $f,g$ 单调增加时,函数 $w$ 还满足区间包含单调性。

  • 性质 3 :设 $h(x)$ 是一个单调增加的凸函数,若函数 $w(l,r)$ 满足四边形不等式并且对区间包含关系具有单调性,则复合函数 $h(w(l,r))$ 也满足四边形不等式和区间包含单调性。

  • 性质 4 :设 $h(x)$ 是一个凸函数,若函数 $w(l,r)$ 满足四边形恒等式并且对区间包含关系具有单调性,则复合函数 $h(w(l,r))$ 也满足四边形不等式。

首先需要澄清一点,凸函数(Convex Function)的定义在国内教材中有分歧,此处的凸函数指的是(可微的)下凸函数,即一阶导数单调增加的函数。

插头DP|轮廓线DP

一个闭合回路

多个闭合回路

联通块

L型

L 型地板:拐弯且仅拐弯一次。

发现没有,一个存在的插头只有两种状态:拐弯过和没拐弯过,因此我们这样定义插头:

0表没有插头,1表没拐过的插头,2表已经拐过的插头。b1代表当前点的右插头,b2代表当前点的下插头

DP套DP

有 $dp_1, f[i]$ 为 $dp_1[n] = i$ 的方案数,求 $f$

设 $dp_2[dp_1]$ 为 $dp_1$ 状态下的方案数

动态DP

将 dp 转换为线段树可以求解的区间问题,动态维护

动态线性DP

动态树形DP

树链剖分,轻链暴力


STL

unordered_map 重载

定义函数


分数

warning:未完全验证


模数

弟弟操作

tourist的模板(用不来)

某出处

注: #ifdef _WIN32部分可能导致 CE


高精度

一个小技巧

a + b == (a ^ b) + ((a & b) << 1)

可以使用 bitset 实现高精度加法

vector版本

压位+vector+符号 版本

int[]版本

食用前请必须注意位数是否足够!

一本通习题
洛谷习题

此版本 压位+数组,支持cin,cout,string,long long转换,比较运算符,四则运算(包括高精度乘/除低精度,取模),支持带符号的减法运算,支持幂运算,开根运算

可以通过开根外所有习题