其实是一个咕了很多东西的blog

动态规划-Undone

线性DP

树形DP

状压DP

数位DP

概率DP

堆 - heap

这个专题主要掌握二叉堆左偏树。一般二叉堆可以满足很多题目要求,仅当需要合并的时候才使用左偏树。

AC自动机 - AC automaton

Goal 这个专题主要掌握普通的Hash(或stl::map),KMP算法AC自动机。AC自动机是一个很多变的数据结构,本质是Trie,但是可以根据fail数组和next数组将其转化成一张。重点是弄懂其fail数组与next数组的工作原理,于是图加上完整的边后就能与DP(注意若状态转移长度只能保留其后缀长度),矩阵快速幂(dijkstra的思想),图论(强连通分量),概率(掷骰子出现某个数字串的概率)。

Hint 出现多个字符串就可以往AC自动机上套。

others BM算法(后缀匹配),扩展KMP算法(任意后缀的前缀数组),RK算法(基于字符串Hash),manacher算法(回文字符串匹配)

最近公共祖先 & 区间极值 - LCA & RMQ

Goal 知道LCA转RMQ==(欧拉序),知道ST表ST树(线段树)==的应用。

RMQ的两种实现方法:ST树(重修改)和ST表(重查询)。

LCA的两种实现方法:寻找最深公共根路径节点(对应倍增与并查集,重单次查询多次修改)和寻找最浅最短路径节点(对应Tarjan算法,重多次查询)。

线段树 & 树状数组

维护一段区间内的DP值。

线段树的应用,注意基本操作之间的差异。

  • 拆分与合并信息。新增维护的量,考虑边界与否。

  • 一般来说虽然线段树常数大,但是用来处理修改和查询的结合的题目比较直观。

  • RMQ问题只能用线段树。

树状数组的应用,注意下标与键值的意义。

  • 可以用于查询第k小和逆序对。

  • 树状数组更容易提高维度。

树链剖分

重链剖分:选取子树最大的节点作为重链,维护DFS序使其链上节点序号连续,且子树序号亦连续。用线段树维护子树与区间修查。

平衡树

技巧:splay和treap都是灵活性高的数据结构,可以根据题意来设置操作。

treap

  • split有两种,按照节点键值和子树大小。
  • merge可以直接返回L或R(方便些),也可以传引用。
  • delete注意只删一个,而无旋treap不支持count,所以把v都提出来,去掉一个,再合并。
  • rotate传参一般传引用,多画图
    查询rank,K-th,pre,sur注意边界,键值等于v的点在哪个子树。
  • reverse推标记,把左右儿子换一下就行。
  • pushdown操作在所有要改变树形态的操作前,pushup在之后。

splay

  • splay一般是(x,y),将x移到y的下方,也有直接移到root。

  • rotate更新关系注意gfa存在与否,这一点在LCT里很重要。

  • ins & del这个就可以count了。记得ins后要splay。

  • pre & sursplay到根,然后while到底。

  • reverse 转到左子树的右子树,打标记。

分治

点分治是处理树上有权路径问题的算法。

点分治和树形DP?其实点分治一部分可以转化为树形DP,点分治重找重心本身也是树形DP。

主要流程(递归):找重心 > 处理子树节点 > 对子树根节点进行计算 > 根据容斥原理删去子树答案 & 找重心

动态树 - LCT

LCT是以Splay 为实现基础的,本质是森林,但splay跟平常的不一样,pushdown操作也需要注意,即关于reverse的处理。

其中涉及两个点操作的都需要access+splayaccess + splay

尤其要注意实边和虚边的处理。还是不太懂

基本操作很多,但是理解为主,代码量很小。

图的生成树

最短路算法(单元/多元)

  1. Floyd:利用动态规划(Dynamic ProgrammingDynamic\ Programming)进行设计,经常利用k层循环的本质出题。
  2. Dijkstra:利用贪心算法(Greedy AlgorithmGreedy\ Algorithm)进行设计,每次选出距离起点最近的点进行Relax,因为只顾及已知距离,无法处理负边权。
  3. SPFA:利用动态规划(Dynamic ProgrammingDynamic\ Programming)进行设计,将队列里的节点进行Relax,并将短于最佳答案的入队。如果存在负环,则一定有环上的点被Relax两次。求最长路,可以将边权取负。
  4. Johnson:将负边权变成正的,然后根据公式进行n次Dijkstra。Dijkstra的推广算法。

最小生成树

最小权重生成树的简称,使所有边权和最小。

  1. Prim:类似Dij的贪心的Relax方式。感觉用处不大。
  2. Kruskal:贪心选择边权小的边,用并查集维护两点是否连通。
  • Ex αEx\ \alpha:增量最小生成树:每加入一条有权边输出当前一次最小生成树。根据回路的性质,只需删除新环中权值最大的边。

  • Ex βEx\ \beta:次小生成树:同上,枚举新环,得到一个删除后使得权值和之差最小。

  • Ex γEx\ \gamma:最小生成树计数:生成最小生成树,得到每种权值的边使用的数量x,然后对于每一种权值的边搜索,得出每一种权值的边选择方案,然后乘法原理。

  • Ex δEx\ \delta最小瓶颈路径:使路上最大边权最小。用Kruskal生成最小瓶颈生成树,树上任意路径E(u,v)E(u,v)都是(u,v)(u,v)的最小瓶颈路径。

  • Ex ϵEx\ \epsilon:最舒适路径:是路上最大边权-路上最小边权最小。

    逆向思维:枚举最小边,尺取法,二分答案。并查集维护连通性。

  • Ex ζEx\ \zeta:多次询问(u,v)(u,v)最大瓶颈路上的最小边权。

    即在最大瓶颈树上寻找最小边,使用倍增LCA。

  • Ex ηEx\ \eta:最小乘积生成树:Undone

  • Ex θEx\ \thetaTo be continue\Rightarrow

拓扑序

​ 拓扑排序后任意点满足连向其的点在其前,其连向的点在其后。

​ 这样有利于DP转移,是DAG-DP的基本顺序,也可以判环,求割点,其实都是维护点转移的顺序。

  • Ex αEx\ \alpha:拓扑序唯一,但是求字典序最小的拓扑序列的时候,可以考虑从出度倒推。

欧拉回路

​ 从任意点出发,每条边只经过一次回到该点,则我们称这张图存在欧拉回路。(一笔画问题)

​ 充要条件:无向图任意点的所有度数为偶数,有向图任意点的入度和出度相同。

差分约束

​ 给出形如xy<=bx-y<=b的不等式,求问题的解。转化为(y,x)=b(y,x)=b,然后跑最短路,无解说明有负环,应该考虑算法。通过代数问题转化为差分约束。

K短路

​ 由最短路的扩展我们知道一个点入队多少次,就得到第几短的路径。设计一个A*进行Spfa。估价函数:反向边跑终点单源最短路。

2-SAT的匹配

​ 引入交替路和增广路的概念。匈牙利算法即不断寻找增广路来更新交替路的过程。有点像网络流。不太懂。

最小环的计算-Undone

图的连通性

强连通分量

tarjan

​ 可以生成一颗dfs/bfs树,并且很有性质。以下四个定义皆使用此树解。
省选之路
​ 如图,黑色为树边,蓝色为前向边,红色为返祖边,绿色为横叉边。

kosaraju

​ 是根据强连通分量独特性质:顺逆皆可到达分量内任意一点,用图和反图来设计的算法。

以下定义仅针对无向图

割点

​ 感性理解即去掉后连通块数量增加。可根据拓扑序结合乘法原理来判断。是否有边跨过是唯一判断标准,那么只要有一个孩子满足dfn[u]<=low[v]即可。
省选之路

​ 即割边。定义同理。比点简单,如果E(u,v)满足dfn[u]<low[v]即可。

双连通分量

​ 删除点或边仍连通的图或分量称为对应的双连通分量。没有横叉边,前向边与返祖边统称跨越边。

双点连通分量

​ 利用栈。儿子满足没有跨越边的子树即为一个点双,包括自己在内。

双边连通分量

​ 删除割边,其他都是边双连通分量。

二分图-Undone

2-SAT

最大匹配——匈牙利算法

网络流

推荐博客

最大流与最小费用最大流

​ 最大流与最小费用最大流,是网络流最基础的两种模型。

FF

​ 单路增广。DFS寻找一条路径并记录前驱,找到路径后再回溯处理边权。O(VE2)O(VE^2)

EK

​ 单路增广。每次使用BFS寻找一条路径并记录前驱,找到路径后再回溯处理边权。O(VE2)O(VE^2)

Dinic

​ 多路增广。预处理优化访问次数。每次计算多条路径,并同时处理边流,减少了运行次数。O(V2E)O(V^2E)

SAP

​ 没用过。据说Gap优化后飞起。

​ 求最小费用最大流时使用Spfa保证是最短路径。

Q 为什么会有最小费用最大流?

​ 1️⃣当一个图有很多路径供选择的时候,自然会产生更优的路径阶级分化

​ 2️⃣当一个图需要求最短路并且有后效性的时候,最短路或DP不适用。

最大流及其变式

​ 最大流,最小割,最小覆盖集,最大独立集等。由二分图引入,均可使用最大流的模型求解。

有上下界的网络流

推荐博客

入题

​ ▶️ 提取题目信息。

​ 点:题目描述的对象,平面图中的点,时间点段等。

​ 边:对象之间的关系,平面图中的边,时间推移等。

​ ▶️ 思考一条路径的意义。

​ 判断是否可以建模。如最大流使得一条路径为所求,最小割则不可以存在路径连通S-T,等等,按照题目抽象出来的本质思考。有了路径,就可以很快确定点和边的含义。

解题

拆点

​ ⬛️ 将入度和出度独立处理,通常和floyd一起使用。

​ ⬛️ 限流,即每个点经过的次数​。点的限制转化为边的限制

​ ⬛️ 时间推移导致点信息的变化和转移。

​ 主要是设计边的流量和费用。一些非常规操作:

​ 1. 点的经过次数(次数即流量)。

​ 2. 流量为inf保证不参与决策,仅起到连接作用。

其他

​ ⚫️ 二分答案,在跑到给定流的情况下求限制值的极值。

​ ⚫️ 无序化有,定义序关系以适应网络流模型中的有向边。

​ ⚫️ 零一点集,源集汇集则分别为01点集,源集内的点即为选择的点。

​ ⚫️ 满流问题,入度=出度,应用于欧拉判环或者平衡问题。

数论

矩阵相关

矩阵运算

普通运算一次为O(N3)O(N^3)的复杂度,C[i][j]=Σi=1na[i][k]×b[k][j]C[i][j]=\Sigma^{n}_{i=1}a[i][k]\times b[k][j]。可优化至O(NlogN)O(NlogN)

快速幂

最常见的用法是优化线性递推,还可以运用到闭合回路中k条边的方案数,AC自动机DP中优化递推。

高斯消元

解n元1次方程组。

数论

素数判定

直接枚举到N\sqrt N判断因数。或者使用Miller-Robin算法(随机算法)。

欧拉函数

表示[1,n)[1,n) 中与 n 互质的数的个数:φ(n)=Σi=1n(gcd(i,n)==1)=n(11p1)(11p1)(11pn),pinφ(n)=\Sigma^{n}_{i=1}(gcd(i,n)==1)=n(1-\frac{1}{p_1})(1-\frac{1}{p_1})…(1-\frac{1}{p_n}),p_i|n

线性筛

埃氏筛,对于每一个质数 x,筛去所有 x 的倍数。

gcd & exgcd

辗转相除法。exgcd是求ax+by=c(gcd(a,b)c)ax + by = c (gcd(a, b) | c) 的解集 (x,y)(x, y),可以用来求逆元。

s(k)=Σi=1n(gcd(i,n)==k)=φ(n/k)s(k)=\Sigma^{n}_{i=1}(gcd(i,n)==k)= φ (n/k)

逆元

a%m/b%ma/b%ma\%m / b\%m \not= a/b\%m,因此需要求b1b^{-1}即b的逆元,使得a%mb1%m=a/b%ma\%m * b^{-1}\%m = a/b\%m。就是在模数意义下去掉除法运算。

特别地,当模数为质数的时候,一个数的逆元就是该数的模数减二次幂。

线性求逆元:i1pi(p%i)1(mod p)i^{−1}≡−⌊\frac p i⌋∗(p\%i)^{-1} (mod\ p) 代码:inv[i]=(ppi)inv[p%i]%p;inv[i] = (p -\frac p i) * inv[p \% i] \% p;

CRT-Undone

组合

组合公式

组合定理

Lucas定理

当组合数需要模一个质数时。C(n,m)%p=C(n/p,m/p)C(n%p,m%p)%pC(n,m)\%p=C(n/p,m/p)*C(n\%p,m\%p)\%p

相关文章:

  • 2021-12-15
  • 2021-08-20
  • 2021-09-26
  • 2022-12-23
  • 2021-09-30
  • 2021-08-11
  • 2021-06-27
  • 2021-09-23
猜你喜欢
  • 2022-12-23
  • 2021-10-27
  • 2021-12-03
  • 2021-12-31
  • 2022-01-10
  • 2022-01-29
相关资源
相似解决方案