省选之路

本文详述了算法竞赛中的数据结构与算法,涵盖了动态规划、树、图、网络流、数论等多个核心主题。动态规划部分包括线性、树形、状压、数位和概率DP;树的讨论点包括堆、AC自动机、最近公共祖先与区间极值、线段树等;图论部分包含最短路、最小生成树、拓扑序等经典算法。此外,还介绍了网络流的几种算法和数论中的矩阵运算、欧拉函数等概念。虽然文章提及了许多未完成的内容,但它为深入理解算法竞赛提供了宝贵的资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其实是一个咕了很多东西的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的处理。

其中涉及两个点操作的都需要 a c c e s s + s p l a y access + splay access+splay

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

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

数据结构技巧

图的生成树

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

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

最小生成树

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

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

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

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

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

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

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

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

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

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

  • E x   θ Ex\ \theta Ex θTo be continue ⇒ \Rightarrow

拓扑序

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

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

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

欧拉回路

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

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

差分约束

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

K短路

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

2-SAT的匹配

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

最小环的计算-Undone

图的连通性

强连通分量

tarjan

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

kosaraju

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

以下定义仅针对无向图

割点

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

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

双连通分量

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

双点连通分量

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

双边连通分量

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

二分图-Undone

2-SAT

最大匹配——匈牙利算法

网络流

推荐博客

最大流与最小费用最大流

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

FF

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

EK

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

Dinic

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

SAP

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

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

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

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

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

最大流及其变式

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

有上下界的网络流

推荐博客

入题

​ ▶️ 提取题目信息。

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

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

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

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

解题

拆点

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

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

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

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

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

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

其他

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

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

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

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

数论

矩阵相关

矩阵运算

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值