review

DP

动态 DP

模板

整体 DP

线段树合并时,当 (x,y) 其中一个没有儿子时,就打标记返回。[PKUWC2018] Minimax [ZJOI2019] Minimax搜索 [CEOI2019] Magic Tree

概率期望 DP

求期望时,可以试试对状态差分。

条件概率:(P(A|B)=frac{P(AB)}{P(B)} Rightarrow E(A|B)=frac{E(AB)}{P(B)})

贝叶斯公式:(P(A|B)=frac{P(B|A)P(A)}{P(B)})

计数转概率:[AGC030D] Inversion Sum

计数 DP

和区间有关的计数大部分都是先离散化转为左闭右开 ([ )) 后再处理。某位歌姬的故事 [APIO2016] 划艇

树形 DP

长链剖分:用 (vector) 实现。Dominant Indices [POI2014]HOT-Hotels [WC2010]重建计划

if(len[y]>=len[son[x]]) son[x]=y,len[x]=len[y]+1;

(dfs) 序优化背包:决策是否加入当前子树。

决策单调性

单调递增:二分栈或分治 实现 单调递减:实现

斜率优化

(x) 单调,(k) 单调,单调队列维护。

(x) 单调,(k) 不单调,凸包上二分。[SDOI2012] 任务安排

(x) 不单调,(k) 不单调,(CDQ) 分治或平衡树维护。[NOI2007] 货币兑换

用李超线段树来维护更方便。[CEOI2017] Building Bridges

树上点分治斜率优化。[NOI2014] 购票

凸优化

[八省联考2018] 林克卡特树 至多选 (k) 个:[CEOI2011] Hotel

注意考虑凸包上共线的情况,就是最后计算答案时不能用 (DP) 求出的个数 (cnt),要用给定的限制 (k)

数据结构

线段树

维护单调栈:楼房重建 [HNOI/AHOI2018] 转盘 区间查询:实现 粉兔文章

李超线段树:模板:[CEOI2017] Building Bridges 线段树合并:CF932F Escape Through Leaf 线段:[HEOI2013] Segment

❌势能线段树

dsu on tree

处理静态子树询问。CF208E Blood Cousins CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

LCT

维护子树和连通块:SP16580 QTREE7 - Query on a tree VII

(access) 染色:「雅礼集训 2017 Day7」事情的相似度

K-D Tree

重构:简单题 打标记:[Ynoi2008] rrusq 方方方的数据结构

注意是平衡树写法,节点上有信息。

01 Trie

整体加 (1)[省选联考 2020 A 卷] 树 整体异或、求 ( ext{mex})[清华集训2016] Alice 和 Bob 又在玩游戏 可持久化:[HEOI2013] ALO

图论

同余最短路

[国家集训队] 墨墨的等式 CF516E Drazil and His Happy Friends

最小环

(Floyd) 外层循环枚举到 (k) 时,用 (dis_{i,j} + val_{i,k} + val_{k,j},i<k,j<k) 更新答案,其中 (dis) 为最短路径长度,(val) 为边权。

二分图

最大匹配必须边:满流,且 (x)(y) 在残量网络上属于不同的强连通分量。

最大匹配可行边:满流,或 (x)(y) 在残量网络上属于同一个强连通分量。

最大匹配必须点:在残量网络上,以 (S) 为起点遍历流量为 (1) 的边,没有遍历到的匹配点为左部图的必须点,以 (T) 为起点遍历流量为 (0) 的边,没有遍历到的匹配点为右部图的必须点。(这里遍历的就是未满流边)

霍尔定理:最大匹配为 (|X|-maxlimits_{S subseteq X}{|S|-|N(S)|}),其中 (N(S)) 是和 (S) 相连的点集。(再做几个相关题)

最小点覆盖 (=) 最大匹配 [USACO05JAN] Muddy Fields G

最小边覆盖 (=) (n-) 最大匹配

最大独立集 (=n−) 最大匹配 CF1404E Bricks

(DAG) 的最小路径点覆盖 (=n−) 拆点二分图最大匹配

(Dilworth) 定理:最长反链 (=) 最小可重链覆盖

网络流

注意流量为实数时的精度问题,不能用极大值减较小值,会舍掉精度。

最小割可行边:满流,在残量网络上不存在 (x)(y) 的路径。(缩点后判断,等价于 (x,y) 属于不同的强连通分量)

最小割必须边:满流,是可行边,在残量网络上存在 (S)(x)(y)(T) 的路径。(缩点后判断,等价于 (x)(S) 属于同一个强连通分量,(y)(T) 属于同一个强连通分量)

退流:要删掉边 ((x,y))(x)(S) 跑最大流,(T)(y) 跑最大流,总流量减去这两个最大流的较小值,然后就能直接删掉 ((x,y)) 了。[SDOI2014] LIS 元旦老人与丛林 [八省联考2018] 劈配

最大权闭合子图:正权点权值和 (-) 最小割。

最大密度子图:二分 (gleqslantfrac{|E|}{|V|}),得 (|E|-|V|×g geqslant0),转化为最大权闭合子图。

❌最小割二元关系:happiness 文理分科 人员雇佣

❌上下界:有源汇转无源汇时记得加 ((T,S,0,inf))。求最小流时,加这条边前就跑一遍最大流,加了后再跑一遍最大流,这条边的流量就是最小流。

❌循环流

[CQOI2012] 交换棋子

[NOI2012] 美食节

[HNOI2013] 切糕

Tarjan

(low_x):在以点 (x) 为根的子树内的点通过非树边的一条边到达的 (dfn) 最小的节点 (y)(dfn) 值,(y) 能到达 (x)

强连通分量:(dfn_x=low_x),更新 (low_x) 时判 (vis_x)

点双连通分量:(dfn_x leqslant low_y)

边双连通分量:(dfn_x < low_y),更新 (low_x) 时判 (link)

圆方树

只有圆方边,圆点度数为去掉该点后形成的连通块个数,方点度数为点双大小。

处理仙人掌时两点一边间不再新建方点,即存在圆圆边。

差分约束

如果我们有一些限制形如 (x_a−x_b<=d)

那么我们可以把它联系到最短路上,如果 (b→a) 有一条长度为 (d) 的边,那么必然有 (x_a<=x_b+d)

这样我们求最短路,可以得到 (x_a) 的最大值

为什么是小于等于号却是最大值呢,因为我们是从正无穷向下规约的

2-SAT

一个存在后另一个必须存在:(x ightarrow y,y^prime ightarrow x^prime)

不能同时存在:(x ightarrow y^prime,y ightarrow x^prime) 必须同时存在:(x ightarrow y,x^prime ightarrow y^prime)

至少存在一个:(x^prime ightarrow y,y^prime ightarrow x) 至多存在一个:(x ightarrow y^prime,y ightarrow x^prime)

不能存在:(x ightarrow x^prime) 必须存在:(x^prime ightarrow x)

选择缩点后编号较小的状态。要连逆否命题。

前缀优化建图:[PA2010] Riddle CF1215F Radio Stations CF1007D Ants CF587D Duff in Mafia

最小树形图

斯坦纳树

[BalticOI 2016 Day2] 城市

虚树

bool cmp(const int &a,const int &b)
{
    return dfn[a]<dfn[b];
}
void build()
{
    sort(s+1,s+tot+1,cmp);
    for(int i=tot-1;i;--i) s[++tot]=lca(s[i],s[i+1]);
    sort(s+1,s+tot+1,cmp),tot=unique(s+1,s+tot+1)-s-1;
    for(int i=2;i<=tot;++i) fa[s[i]]=lca(s[i],s[i-1]);
}

注意清空的复杂度。

欧拉图

void dfs1(int x)// 无向图
{
    for(int &i=head[x];i;i=e[i].nxt)
    {
        if(vis[i]) continue;
        int l=i;
        vis[i]=vis[i^1]=true,dfs1(e[i].to),p[++cnt]=l&1?-(l>>1):(l>>1);
    }
}
void dfs2(int x)// 有向图
{
    for(int &i=head[x];i;i=e[i].nxt)
    {
        if(vis[i]) continue;
        int l=i;
        vis[i]=true,dfs2(e[i].to),p[++cnt]=l;
    }
}

Kruskal 重构树

for(int i=1;i<=m;++i)
{
    int x=find(ed[i].x),y=find(ed[i].y);
    if(x==y) continue;
    val[++tot]=ed[i].v,add(tot,x),add(tot,y);
    fa[x]=fa[y]=f[x][0]=f[y][0]=tot;
    if(tot==2*n-1) break;
}

三元环

for(int i=1;i<=m;++i)
{
    int x=ed[i].x,y=ed[i].y;
    if(deg[x]>deg[y]||(deg[x]==deg[y]&&x>y)) swap(x,y);
    add(x,y);
}
for(int x=1;x<=n;++x)
{
    for(int i=head[x];i;i=e[i].nxt) vis[e[i].to]=x;
    for(int i=head[x];i;i=e[i].nxt)
        for(int j=head[e[i].to];j;j=e[j].nxt)
            if(vis[e[j].to]==x)
                ans++;
}

四元环:

bool cmp(int x,int y)
{
    return deg[x]==deg[y]?x<y:deg[x]<deg[y];
}
for(int x=1;x<=n;++x)
{
    int y,z;
    for(int i=head[x];i;i=e[i].nxt)
        if(cmp(x,y=e[i].to))
            for(int j=head[y];j;j=e[j].nxt)
                if(cmp(x,z=e[j].to))
                    cnt[x]+=vis[z],cnt[y]+=vis[z],cnt[z]+=vis[z]++;
    for(int i=head[x];i;i=e[i].nxt)
        if(cmp(x,y=e[i].to))
            for(int j=head[y];j;j=e[j].nxt)
                if(cmp(x,z=e[j].to))
                    cnt[y]+=--vis[z];
}

k 短路

哈密顿图

P3561

Prufer 序列

长为 (n-2),值域为 ([1,n])(i) 的出现次数为其对应的有标号无根树中 (i) 的度数减一。

(k) 个连通块,加 (k-1) 条边使图连通的方案数为 (n^{k-2}prod a_i)

数学

线性基

本质是消元,可以用来求解异或方程组。求第 (k) 小异或和时,将线性基的第 (i) 位消元为只有二进制中的第 (i) 位为 (1) 即可。实现

多项式

牛顿迭代:

[large g(x) equiv g_0(x) - frac{f(g_0(x))}{{f}'(g_0(x))} pmod{x^{2n}} ]

类欧几里得算法

欧拉定理

[large a^b equiv a^{b mod varphi(m)+varphi(m)} pmod{m},b geqslant varphi(m) ]

中国剩余定理

(crt):解为 (x=sumlimits_{i=1}^na_ifrac{M}{m_i}t_i),其中 (M=prodlimits^n_{i=1}m_i,frac{M}{m_i}t_iequiv 1 pmod{m_i}),即 (t_i)(frac{M}{m_i}) 在模 (m_i) 意义下的逆元。(注意计算 (frac{M}{m_i}t_i) 时,不要对 (m_i) 取模)

(excrt):两两合并方程:

[largeegin{aligned} &egin{cases} x equiv a_1 pmod{m_1} \ xequiv a_2 pmod{m_2} \end{cases}\ &x=a_1+m_1t_1=a_2+m_2t_2\ &m_1t_1-m_2t_2=a_2-a_1\ &x equiv m_1t_1+a_1 pmod{ operatorname{lcm}(m_1,m_2) } end{aligned} ]

ll excrt()
{
    ll ans=a[1],M=m[1];
    for(int i=2;i<=n;++i)
    {
        ll g=exgcd(M,m[i]),tmp=((a[i]-ans)%m[i]+m[i])%m[i];
        if(tmp%g!=0) return -1;
        ans+=mul(x,tmp/g,m[i])*M,M*=m[i]/g,ans=(ans%M+M)%M;
    }
    return ans;
}

卢卡斯定理

扩展卢卡斯定理:

[large f(n) pmod{p^k}=fleft(leftlfloor frac{n}{p} ight floor ight)left( prod_{i=1,p otmid i}^{p^k} i ight)^{leftlfloor frac{n}{p^k} ight floor} prod_{i=1,p otmid i}^{n mod p^k} i pmod{p^k} ]

(n) 小,(p) 大,(p) 为合数时计算组合数的方法:预处理阶乘时不算 (p) 质因子的贡献,这样就有了逆元,计算组合数时再加上质因子的贡献。CF896D Nephren Runs a Cinema

取模技巧:[CEOI2004] Sweets [SDOI2013] 项链

BSGS

(sqrt p) 时要上取整。要注意 (exBSGS) 解比较小的情况。

Pollard-Rho

置换群

(Burnside) 引理:

[large L=frac{1}{|G|}sum_{fin G}c(f) ]

(Pacute olya) 定理:

[large L=frac{1}{|G|}sum_{fin G}k^{m(f)} ]

筛法

博弈论

反演

莫比乌斯反演:

[largeegin{aligned} &mu imes 1=epsilon ,varphi imes 1=id ,mu imes id=varphi \ &f=g imes 1iff g=f imes mu end{aligned} ]

二项式反演:

[largeegin{aligned} f(n)=sum_{i=m}^ninom{n}{i} g(i) &Leftrightarrow g(n)=sum_{i=m}^n(-1)^{n-i} inom{n}{i} f(i)\ f(n)=sum_{i=n}^minom{i}{n} g(i) &Leftrightarrow g(n)=sum_{i=n}^m(-1)^{i-n} inom{i}{n} f(i) end{aligned} ]

注意是钦定,不是至少至多。

单位根反演:

[large [nmid k]=frac{1}{n}sum_{i=0}^{n-1}omega_n^{ik} ]

原根

(delta_p(g) = varphi(p)),则 (g) 为模 (p) 的一个原根。最小原根大小是 (O(p^{frac{1}{4}})) 的,用 (g^{frac{varphi(p)}{p_i}} ot equiv 1 pmod{p}) 检验暴力求即可。

二次剩余

字符串

border

(WPL):若 (i,j) 是字符串 (s) 的周期,且 (i+jleqslant |s|),则 (gcd(i,j)) 也是 (s) 的周期。

AC 自动机

要注意根为 (0)

后缀自动机

若维护了一个节点的 ( ext{endpos}) 集合的最小位置,新建 (nq) 时,要从 (q) 继承。

广义后缀自动机暴力跳 (fa) 时打标记来保证正确性(每个串只有一次贡献)和复杂度((nsqrt n))。[SCOI2012] 喵星球上的点名

回文树

扩展 KMP

Lyndon Word

计算几何

凸包

半平面交

闵可夫斯基和

杂项

莫队

CDQ 分治

模拟退火

根号分治

CF840E In a Trap

原文地址:https://www.cnblogs.com/lhm-/p/14381438.html