总结复习
不知不觉已经两年 OI 了
主要是回顾一下以前做过的一些题目,
由于开始写这个玩意的时间比较靠后,所以漏了很多好题
慢慢加
基础算法
- 递归 P1228 地毯填补问题 抓住问题相似性(本题中:每一层都要留空一块)
- 二分答案+差分 P1083 [NOIP2012 提高组] 借教室 直接差分的问题在于无法找到具体是哪个人,而暴力 \(O(n^2)\) 不过,考虑二分答案,差分判断,\(O(n\log n)\)
- 二分答案 NOIP2015 提高组 跳石头 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 裸的二分
- 并查集 NOI2001] 食物链 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 三种关系
- Hash P2037 电话号码 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 桶就完事
- 贪心 AGC018B 干掉当前人最多的
- 贪心 HDU 6000 用堆处理出洗完前 i 件需要的最短时间,烘干的时间,然后用最长的洗的时间配合最短的烘干时间即可(在 Vjudge 提交语言选 G++ !!!)
- 边带权并查集 [P5937 CEOI1999]Parity Game - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 模板。一个询问可以转化成 sum[r] 和 sum[l-1] 的奇偶性是否相同。考虑离散化。设 d[x] 表示 x 和并查集上 f[x] 的奇偶性是否相同,那么两个点 x,y 的奇偶关系就是路径压缩后 d[x]^d[y] 。合并时,先路径压缩,让 f[fx]=fy,则 d[fx]d[x]d[y]=opt ,那么 d[fx]=d[x]d[y]opt 。
- 单调栈LIS [P1020 NOIP1999 普及组] 导弹拦截 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- 堆 [P7913 CSP-S 2021] 廊桥分配(民间数据) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 可以发现如下性质: 有 \(i\) 个廊桥时,停靠的飞机在有 \(i+1\) 个廊桥时至少都可以停靠在原来位置 \(\to\) 第 \(i\) 个廊桥和 \(i+1\) 个廊桥之间不干扰。有一个显而易见的思路是,对于国内和国外区,分别处理出分配 \(i\) 个廊桥可以停靠的飞机数。考虑开一个小根堆,每碰到一个飞机到达,插入离开时间和用的廊桥的编号,离开的时候弹出,并将对应廊桥的编号的可停靠飞机数 ++。廊桥的编号另开一个小根堆维护。
- 思维题模拟 Frog Traveler 维护可以扩展到的最大范围
- 并查集维护直径 20211030 连通块 - Problem - FZUOJ (fzoi.top) 把操作倒着来,一个点联通块内最远点肯定是直径两个端点之一,联通块合并的时候的新直径端点必然在四个端点之中。注意合并时,端点的匹配有 6 中情况
- 链表 turing machine - 题目 - FZUOJ (fzoi.top) 从后往前处理每一个 \(0\) ,发现每一个 \(0\) 随着时间的运动轨迹是基于后面的一个 \(0\) 的,要么不变,要么向后一步。表现在图像上,就是向量 (0,1) 和向量 \((1,1)\) 的交替出现,而这个 \(0\) 位置的变化量就是第二种向量数量,考虑链表维护这个图像。
搜索
- 毒瘤BFS 20210925约数 (pb day1) - 题目 - FZUOJ (fzoi.top)
- BFS NOIP2002 提高组] 字串变换 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- 二进制枚举状态 20211006 纸牌游戏(VanishD day2) - 题目 - FZUOJ (fzoi.top) 14个操作,做与不做。考虑预处理出区分任意两个需要的操作,考虑已经选出了一组方案,如果存在两个卡片,无法判断,false。
- DFS [HDU 6986]Kanade Loves Maze Designing - 题目 - FZUOJ (fzoi.top) O(n^2) 即可
数论/数学
-
推狮子+组合数 20210925 翻转(pb day1) - 题目 - FZUOJ (fzoi.top) ,发现两个翻转区间不能有重叠(除非存在包含关系),首先考虑 \(n==k\) 的特殊情况,此时每个数肯定都要变成 0 (一次反转干掉一个1),而我每次选择一个区间,会将这个序列分成 3 个部分,所以答案 = \(1\times3\times5\times 7\dots \times (2n-1)=(2n-1)!!\) 。考虑把剩下的 \(n-k\) 个 1 插入 \(n+k-1\) 个 \(0\) 之间即可, \(C_{n+k}^{n-k}\)
-
容斥 20211006 矩阵计数(VanishD day2) - 题目 - FZUOJ (fzoi.top) 设 f[i] 表示刚好 i 行最小值大于 n 的情况,g[i] 表示至少有 i 行。 \(f[i]=\sum \tbinom{j}{i} g[j] \times (-1)^{j-i}\) ,\(g[i]=\tbinom{n\times n-n}{i\times n}\times (n\times i)!\times (n\times(n-i))!\times \tbinom{n}i\)
-
简单容斥 [P3197 HNOI2008]越狱 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 不相邻方案数:\(m^n-m\times(m-1)^{n-1}\)
-
整除分块 [P2261 CQOI2007]余数求和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 与 \(\lfloor\frac ni\rfloor\) 相等的 \(\lfloor\frac n{i^{\prime}}\rfloor\) 的 \(i^{\prime}\) 的最大值为 \(\lfloor \dfrac{n}{\lfloor\frac{n}{i}\rfloor}\rfloor\)
-
完全剩余系 20211102 数字变换(num) - Problem - FZUOJ (fzoi.top)
所谓 \(2^k\geq p\) 一定有解:可以反证法证明对于 \((a,p)=1\) 且 \(p\) 为质数, \(a_{0...p-1}\) 在模 \(p\) 意义下互不相同,既是 \(p\) 的一个完全剩余系
-
线性基 [TJOI2008]彩灯 模板
-
Nim博弈+线性基 [CQOI2013]新 Nim 游戏 见题解
-
线性筛 20211115 数字 - 题目 - FZUOJ (fzoi.top) 容易发现答案即是两个数字分解质因数后最长相同后缀。这部分相同后缀一定是它们 GCD 的一部分。如若 GCD 很大,说明剩下的部分很少,枚举一下剩下的最大的质因子即可,GCD 很小,对 x,y 进行分解,看在 prime<=gcd 的范围内是否可以分解完即可。
-
整除分块 20211117 你还没有卸载吗(game) - 题目 - FZUOJ (fzoi.top) 容易发现 \(\lfloor\frac{a_1}x\rfloor\) 的取值不超过 \(\sqrt a_1\) 种
-
斐波那契 20211117 你还没有AK吗(rand) - 题目 - FZUOJ (fzoi.top) 容易发现问题可以转化成 \(f_ix+f_{i+1}y=C\) 的解的数量,可以考虑用 exgcd 解,更可以发现性质: \(x=-f_{i-1},y=f_{i-2}\) 优化掉一个 log ,过了
-
带删除线性基 「模板」线性基 - 题目 - FZUOJ (fzoi.top) 线性基详解_a_forever_dream的博客-CSDN博客_线性基
图论
-
二分图染色 游戏 - 题目 - FZUOJ (fzoi.top) 题目条件可以转化为1、2 3、4 \dots 颜色不同,在把同一个学校的人连边,容易证明不存在奇环,染色输出方案即可。
-
最短路+缩点 P3008 USACO11JANRoads and Planes G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 发现可以把道路所成一个连通块,那么最后会得到一个 DAG
-
网络流 Topcoder SRM556DIV. OldBridges 利用无向边性质,转化流量流向
-
二分图匹配 [P2825 HEOI2016/TJOI2016]游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 经典,行和列连边
-
MST [海亮NOIP集训]最小边权和[day9] - 题目 - FZUOJ (fzoi.top) 经典,在最小生成树过程中计算答案
-
差分约束系统 「HNOI2005」狡猾的商人 - 题目 - FZUOJ (fzoi.top) 模板
-
直径+树上计数 ABC221F 以树的直径的中点为根(要求具体路径,所以不能用 dp 求直径,要两边 dfs)dia 出一棵树,讨论直径长度奇偶性计算贡献
-
双连通分量 20211020 画图 - 题目 - FZUOJ (fzoi.top) 容易发现最后所有的点双会变成一个完全图
-
强连通分量 间谍网络 - 题目 - FZUOJ (fzoi.top) 显然,同一个强连通分量内,只需要支付最少的那一个间谍。
在强连通分量之间,如果有一条边从强连通分量 \(u\) 指到强连通分量 \(v\) ,显然 \(v\) 不花钱
-
点双+二分图染色 「POJ2942」Knights of the Round Table - 题目 - FZUOJ (fzoi.top) 注意到题目是说”所有会议都不能出席“。不妨建一个补图,那么条件转化为不在任意一个奇环中,环可以转化为点双。考虑先求出补图的点双,容易证明:
- 如果两个骑士不在同一个点双中,它们不能同时出席
- 如果一个点双中存在奇环,那么这个点双中每一个点都至少被一个奇环包含
也就是说,所有含奇环的点双中所有点都可以。上面的第一条是必要性,第二条是充分性,所以这是一个充要条件。有结论:
点双连通分量如果不是二分图,那么所有的点都在奇环上
-
Kruskal重构树 「NOIP2013」货车运输 经典
-
最小生成树+树剖 「BJWC2010」 次小生成树 - 题目 - FZUOJ (fzoi.top) 求出最小生成树后,考虑换边。枚举非树边 \((x,y)\) ,与 \(x,y\) 树上路径最大,次大值比较即可。
-
Johnson全源最短路 P5905 【模板】Johnson 全源最短路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
-
对偶图最小割 狼抓兔子 - 黑暗爆炸 1001 - Virtual Judge (vjudge.net) 发现题目既是即是求从 \(s\) 到 \(t\) 的最小割,但直接 \(n^2m\) 的 \(Dinic\) 显然不是很可靠(仍然能过,毕竟 \(Dinic\) 优化后复杂度玄学),考虑转对偶图 \(dijkstra\) \(O(V\log V)\)解决
-
树链剖分 20211026 Path - 题目 - FZUOJ (fzoi.top) 可以想到连边条件:第二次踏上同一条路径 或 路径上存在两个以上个未来要走的点,树剖维护。
-
二分图最小点覆盖 [「POJ2226」 USACO05JAN]Muddy Fields - 题目 - FZUOJ (fzoi.top) 最小点覆盖=最大匹配
-
网络流 勇闯法法塔 - 题目 - FZUOJ (fzoi.top) 如果一个地方可以打两遍,那么就是二分图最小点覆盖经典例题。不能打两次,考虑网络流。问题等价于给每个格子赋上“横”或“竖”,代价就是 (赋上的方向下一格是墙的格子个数+方向不同的相邻格子 对数)/2。跑一下最小割就行了。
-
Dinic玄学优化 P4722 【模板】最大流 加强版 / 预流推进 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 优化1:我们考虑边权非常大,但是有种优化是我们把边权按照2进制中的位数分段,然后一段内的单独跑一次dinic,最后把增广的累加。
优化2:我们先把原边加入图中,做完上述的分段操作后,再把反向边加到图中,再做一次上述分段操作。
-
最大费用最大流 K Subsequence - HDU 6611 - Virtual Judge (vjudge.net) 不相交选择问题可以转网络流问题,从超级源点向源点连一条流量 \(k\) ,费用 0 的边,每个入点从源点连流量1 费用0的边,入点向出点连流量1 费用 a[i] 的边,若 \(i<j且a[i]\leq a[j]\) ,i 的出点向 j 的入点连边流量1 费用0,出点向汇点连流量1 费用0。考虑到求最大费用,spfa 会被卡,考虑通过改变边权正负来把最长路到最短路,然后给边权加上一个势能即可。
-
有源汇上下界最小费用最大流 P7173 【模板】有负圈的费用流 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) RT
-
树链剖分+线段树区间合并 [P2486 SDOI2011]染色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) RT,注意细节:两个链在 LCA 处合并时需要特殊判断一下
-
"二维"最短路 https://www.fzoi.top/problem/5036 \(vis[i][j]\) 表示点 \(i\) 在体力 \(j\) 时是否经过
-
分层图最短路 「JLOI2011」飞行路线 - 题目 - FZUOJ (fzoi.top) RT
-
虚点+最短路 [ BZOJ 4152]The Captain 先离散化,坐标轴上的点是虚点,一个实点 (x,y) ,对应在虚点 x,y 之间连一条权值为 0 的边,x,y轴上虚点顺次联边,权值为坐标差值。
-
最短路建模 [BZOJ 4289]PA2012 Tax 见题解
-
最小生成树 「PA2014」Kuglarz 容易发现一个询问 \(l,r\) 可以视作联边 \((l,r+1)\) ,目标是花最小费用使得 1...n+1 这 n+1 个点联通。
-
竞赛图+哈密尔顿环+DP [BZOJ 4727]Turysta [BZOJ 4727: POI2017]Turysta - NeighThorn - 博客园 (cnblogs.com)
-
**Borvuka + Trie ** CF888G 考虑把点从小到大插入一颗 Trie 树,显然,对于每一个有两个儿子的点,我们可以将其两颗子树看作是说两个联通集合,那么现在的目标既是说在这两个集合之间找到一条最小的边。遍历左子树,在右子树寻找。当前层做完后,递归到儿子进行。
-
上下界费用流+射线法 白鸽 首先存在欧拉回路的条件是所有非孤立点都与一号点连通,并且每个点的度数都是偶数。 一个简单的想法,把每条边绕原点旋转在的角度记为这条边的费用(如果是负的就把这条边反向),我们先把所有的费用都加在一起作为初始的答案。那么显然会有一些点的度数不符合条件。考虑费用流,对于一条边(u,v)(u,v)我们从uu向vv连一条费用为2∗这条边费用2∗这条边费用的边,表示将这条边反向。对于入度>出度入度>出度的点,从SS向这个点连费用是1,流量为(入度−出度)/2(入度−出度)/2,出度>入度出度>入度的点向TT连边。跑最小费用流即可。
由于边权不一定为整数,费用流会跑的比较慢。由于绕的圈数一定是整数,所以可以用射线法:从原点射出一条射线,如果边从左到右跨过费用为1,反之为-1。在新图上做费用流答案就费用是整数了。可以把原费用流看作是更正答案,而与 ST 连边是为了满足度数限制,所以入度和出度应该是原方向的入度
-
2-SAT 「POJ3683」Priest John’s Busiest Day - 题目 - FZUOJ (fzoi.top) 每一段时间看作一个点, \(n^2\) 判断连边,跑 Tarjan
-
2-SAT [POI2011]KON-Conspiracy - 题目 - FZUOJ (fzoi.top) 显然,如果 \(i\) 认识 \(j\),那么当 \(i\) 为同谋的时候,\(j\) 必为后勤。如果 \(i\) 不认识 \(j\) ,那么当 \(i\) 为后勤的时候, \(j\) 必为同谋。连边,跑 2-SAT 并求出一个可行解。定义\(i\) 的交换点:如果 \(i\) 为后勤且 \(i\) 认识同谋 \(j\) ,如果 \(i\) 为同谋且 \(i\) 不认识后勤 \(j\) 。显然,若 \(i\) 只有一个交换点且那唯一一个交换点没有交换点, \(i\) 可以换到另外一个集合。若 \(i\) 没有交换点而且 \(i\) 所属集合大小 >1 ,那么 \(i\) 可以和另一个集合的这样的点交换,设这样的点叫做自由点,显然,答案还应该加上左边自由点个数*右边自由点个数。
-
2-SAT [P3825 NOI2017] 游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 枚举 \(x\) 究竟是 \(a,b,c\) ,转化为标准 2-SAT
-
费用流改造 HDU6978 New Equipments II - 题目 - FZUOJ (fzoi.top) 发现一个优秀的性质叫做对于一个右部点而言,被最大的左侧点标记后,就不可能与其他左侧点匹配,根据此,BFS 模拟网络流过程即可。
-
欧拉回路 地图 - 题目 - FZUOJ (fzoi.top) subtask3 提示了欧拉回路。容易发现,在 subtask3 的条件下,如果存在奇数个奇环就无解,反之只需要找到一条欧拉回路然后交替染色即可。考虑对于那些度数为奇数的点,向虚点 \(0\) 连边,因为题目要求的是差的绝对值 \(\leq 1\) ,所以在新图上跑欧拉回路形成的染色方案仍然可行。
-
最短路 不知道高到哪里去了 - 题目 - FZUOJ (fzoi.top) 考虑先求出以杀手为起点的单源最短路,而后二分人的速度,在求解以人为起点的单元最短路时加上限制条件。注意由于这里值域较小,可以用桶代替堆优化 Dijkstra
-
01-BFS Small Multiple - 题目 - FZUOJ (fzoi.top) 发现一个数+1 会增加1费,\times 10 却可以白嫖,从 0 开始跑 01-BFS ,跑到第一个点使得这个点 %k==0
-
最短路径树 20211117 赛道改造(road) - 题目 - FZUOJ (fzoi.top) 首先建出一颗最短路径树,考虑每一条非树边 (u,v) 的影响其实就是在树上从 u 到 v 的每一条边在提高代价的时候新最短路可能会走到这个非树边,考虑贡献。暴力贡献可以使用树剖,过于暴力,考虑“树上并查集”,对每一条非树边的贡献排序后,显然,被之前的非树边贡献过的边不用被之后的边更新。把更新过的边的两个端点并入一个并查集即可。
-
同余最短路 跳楼机 模板题 连边 $(i,(i+y)%x,y) (i,(i+z)%x,z) $ 跑出最短路 \(d\) ,答案即为 \(\sum \frac {h-d[i]}x+1\)
-
DSU on tree CF208E 模板
字符串
- Trie 树 http://www.fzoi.top/problem/4903 答题卡 手动模拟样例,转化问题成短串第一个字母外和长串后缀相同,第一个字母在长串之前出现过,trie 树上 dp
- KMP 变形 P5256 JSOI2013编程作业 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 改变两个字符相等的条件:到上一个相同字符的距离相等,同时注意到上一个字符可能不在匹配范围内的判断
- exKMP+Manacher http://codeforces.com/gym/101981 MEDIOCRE STRING PROBLEM 转化问题,\(S_1+S_2+T\) ,假设已知 \(𝑆\) 中每个位置拓展的最长回文半径 \(𝑝𝑖\) 那么对于半径 \(pi\) 的回文,对应的方案要求 \(𝑆1\) 和 \(𝑇\) 对称,且 \(𝑆1\) 的右端点固定,把 \(𝑆\) 反过来做 exKMP 即可。注意到最后统计答案的时候,需要差分计算 右端点在 \(i\) 的回文串个数,否则答案会漏很多
- KMP 循环节 Problem - 3746 (hdu.edu.cn) \(kmp\) 一遍后,最小循环节就是 \(n-kmp[n]\)
- AC自动机+FAIL树上计算 NOI2011 阿狸的打字机 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 首先建出 AC 自动机和 \(fail\) 树,容易发现,对于一个询问 \((x,y)\) ,我们不妨让 fail 树的根到 fail 树上的 y 这一条路径上的点全部+1,那么 \(x\) 的重复次数便是 \(x\) 在 fail 树上子树中1的数量。这是因为如果 \(x\) 在 fail 树的子树上如果存在 1,假设这个节点是 z,那么由 fail 的性质,字符串 \(x\) 可以通过在尾部增加字符的方式变成 z,而 \(z\) 为 1,也就是说 z 是 \(y\) 的子串。需要注意的是,因为我们在得到 fail 数组的时候对原 trie 树进行了修改,所以我们最后在 trie 上 dfs 的时候需要在原 trie 的 copy 上进行,不然就会死循环
(卡了我好久 - 后缀数组+单调栈 [P4248 AHOI2013]差异 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 建立后缀数组后,考虑每一个 \(height[i]\) 对答案的贡献。知道对于排名分别为 \(i,j\) 的两个字符串,最长公共前缀为 \(\min_{l<k\leq r}\{height[k]\}\)
- AC自动机+栈 「USACO2015FEB」Censoring (Gold) - 题目 - FZUOJ (fzoi.top) 注意到我们求解 \(fail\) 的时候有一个对 trie 树进行修改的操作,这个操作实际上与 \(kmp\) 跳 \(next\) 数组类似。考虑开一个答案栈,把 S 放进 AC 自动机里面跑,匹配就退栈即可
- AC自动机+DFS找环 POI2000」病毒 父节点到子节点看作一条单向边,失配指针nxt[]指向的也看作一条单向边,最后会形成一个图。 如果在这个图中找到一个环,且不存在结束标记,那么存在一个以环为循环的无限长的安全代码。 注意:如果一个点的 fail 指向的位置有结束标记,这个点即使没有结束标记也需要加上结束标记
- AC自动机+DP 「JSOI2007」文本生成器 注意到 \(fail\) 树的传递性质。用所有的情况减去不可读的情况(跑不到单词结尾节点的情况)。不可读的情况数量可以用 d p 求。设 \(f[i][j]\) 表示匹配了 i 个字符,现在到 j 号节点的不可读情况数量,从父亲往儿子转移。
- Manacher 「POI2010」Antisymmetry - 题目 - FZUOJ (fzoi.top) 修改字符相同的定义即可,每一个 i 的贡献为 \(p[i]/2\)
- KMP [POI2006]OKR-Periods of Words 画图观察,容易发现 KMP 性质。
- KMP+DP 「CF432D」 Prefixes and Suffixes - 题目 - FZUOJ (fzoi.top) 题目要求的相同前后缀有明显的 KMP 味道,考虑计数,设以 \(i\) 为结尾的“完美子串” 出现 \(f[i]\) 次,有刷新: \(f[kmp[i]]+=f[i]\) ,注意应该倒序刷新
- EXKMP [CF126B]Password 通过 exkmp,求得 z 数组通过 z[i]+i==len判断出这个串既是前缀又是后缀 ,maxn记录当前最大的 z,如果说我们已经找到了一个后缀前缀,并且在 i 前面的最大的 z[x] 是要比 n-i 长的,说明在中间至少也出现了一个相同的。求出最大的 \(i\) 满足 \(z[i]+i=n\) 并且 \(\exist j<i,s.t.z[j]>=n-i\) ,答案即为 \(s[1..z[i]]\)
数据结构
- 线段树区间最小 P1083 [NOIP2012 提高组] 借教室 显然,维护区间最小值即可,注意常数
- 主席树 20210925数据结构 (pb day2) - 题目 - FZUOJ (fzoi.top) 发现可以对于每个 \(w\) ,用一棵线段树维护每个位置的值是否 \(\geq w\) 。 那么一次修改就是把 \(x\) 的线段树的 \([l,r]\) 贴到 \(x+1\) 的线段树上。 用可持久化线段树维护即可。
- 树状数组二维偏序 ABC221E 一对满足 \(a_i<a_j\) 的点对的贡献是 \(2^{j-i-1}=\dfrac{2^j}{2^{i+1}}\) , 转二维偏序问题,贡献变成了 bit.add((2的逆元)^i+1) ,\(bit.ask(i)\times 2^i\)
- 树状数组逆序对 楼兰图腾 - 题目 - FZUOJ (fzoi.top) 经典模板
- 树链剖分 「BZOJ2157」旅游 模板
- 线段树区间hash判断字符串大小 KJF的字符串 - 题目 - FZUOJ (fzoi.top) 字符串之间可以形成一种树形结构,而有连边的两个字符串仅有一个字符不同,考虑动态开点线段树维护 hash 值。此时,通过线段树,我们可以比较两个字符串,如果左区间 hash 相等,比右区间,否则左区间,直到叶子节点分出大小。
- 线段树区间最小+单调栈 easy - 题目 - FZUOJ (fzoi.top) 原条件等价于 \(max-min+1-cnt\leq 0\) ,\(cnt\) 为区间不同数的个数。注意到 \(max-min+1\) 增长速度大于 \(cnt\) ,故可改写成 \(max-min-cnt+1=0\) ,而单个点一定满足条件且为 0,所以考虑固定 \(r\),考虑用线段树维护 \(max-min-cnt\) ,那么答案就是最小值的个数(即0的个数)
- 线段树维护单调栈(单侧递归) P4198 楼房重建 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 经典例题
- 线段树区间最大+尺取法 [P1712 NOI2016] 区间 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 离散化,将线段按长度排序,满足尺取法条件。假设现在双指针 \(l,r\) ,即选择 \(l,r\) 区间的线段,在线段树上修改即可,看 \(t[1].mx\) 是否大于 m(覆盖次数),若小于,\(r++\) ,大于 \(l--\)
- 线段树二分 CF689D Friends and Subsequences - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 考虑线段树维护区间最值,考虑固定左端点 l,因为 min/max 的单调性, r 可以取的范围是一个区间。通过线段树求出最小的 \(k1\) ,使得 \(\max_{i=1}^{k_1}a_i>\min_{i=1}^{k_1}b_i\) ,求出最小的 \(k2\) ,使得 \(\max_{i=1}^{k_2}a_i\geq \min_{i=1}^{k_2}b_i\) ,那么,区间 \([k2,k1)\) 都满足条件。考虑如何求解 \(k1\) ,当我们线段树询问到一个整体的块的时候(L<=l&&r<=R),判断当前a最大值和b最小值的关系,如果此区间有答案,那么下去看一眼左区间即可(看一眼->递归一次)。\(k2\) 同理。
- 线段树分治 P5227 AHOI2013连通图 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 发现每个点的出现时间是一段段区间,离线处理出每条边被删除的位置,解决这个可以用 m 个 vector 解决。对于每一条边,将其挂在 " 该边出现的时间区间对应的线段树节点 " 的 vector 上。最后配合可撤销并查集扫一遍即可。
- 线段树分治 P5787 二分图 /【模板】线段树分治 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 模板,扩展域并查集维护二分图
- 线段树优化建图 CF786B Legacy - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 建立线段树 TreeIn ,TreeOut
- 单调栈/悬线法 [HDU 6957]Maximal submatrix - 题目 - FZUOJ (fzoi.top) 单调栈裸题。注意到子矩阵连续
- 线段树括号匹配 ABC223F 模板
- 线段树二分+区间合并 20211020 交换 - 题目 - FZUOJ (fzoi.top)
- 边分治 [BZOJ2870]最长道路 Tree
- 左偏树 P3377 【模板】左偏树(可并堆) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 堆的合并,hsfzLZH1 的博客 - 洛谷博客 (luogu.com.cn)
- ST+二分 与众不同 loj10121 与众不同(ST算法)(二分)_A_Bright_CH的博客-CSDN博客
- 二维ST表 「HAOI2007」理想的正方形 - 题目 - FZUOJ (fzoi.top)
- 线段树区间min区修+贪心 Optimal Insertion 有贪心思路:优先让 \(b_i\) 小的更优,有性质 b 升序。发现一个新点在位置 \(i\) 的贡献既是其左边大于它的数的数量+右边小于它的数的数量,考虑线段树维护。对于所有的 \(j\) 满足 \(b_i\leq a_j\leq b_{i+1}\) ,线段树上 \([1,a_j)+1,(a_j,n)-1\) 。(看代码)
- 线段树找第一个为0位置 [GDKOI2021TG DAY2]群岛 - 题目 - FZUOJ (fzoi.top) 线段树维护区间最小值。区间 \([a_i,i]\) 整体+1,对于一个询问,找到第一个为 \(0\) 的位置即可
- ST表+堆 「NOI2010」超级钢琴 - 题目 - FZUOJ (fzoi.top) 使用 ST 表 \(O(n\log n)\) 预处理出一个区间的最优位置,把三元组 \((o,l,r)\) 放入堆中,以区间 \([o,l\dots r]\) 前缀最优值为比较。每次在堆中取出一个三元组 \((o,l,r)\) 时,可以把 \((o,l+1,r)\) 和 \((o,l,r-1)\) 加入堆中。
- 分块 「BZOJ2821」作诗 - 题目 - FZUOJ (fzoi.top) \(n\sqrt n\) 预处理 \(sum[i][j]\) 表示前 \(i\) 块中 \(j\) 的出现次数,\(f[i][j]\) 表示块 \(i\) 到块 \(j\) 的答案。每次询问 \(\sqrt n\) 回答。
- 分块 数列分块入门 6 - 题目 - FZUOJ (fzoi.top) 直接 \(\sqrt n\) 暴力插入,在块过大时,暴力重建(替罪羊树思想)
- 分块 数列分块入门 9 - 题目 - FZUOJ (fzoi.top) \(n \sqrt n\) 预处理 \(f[i][j]\) 表示第 \(i\) 块到 \(j\) 块的答案。vector[i] 存储数值 \(i\) 的出现位置,查询区间 \([l,r]\) 中 \(c\) 出现次数既是 \(upper\_bound(vector[c].begin,end(),r)-lower\_bound(,,l)\)
- 分块 磁力块 - Problem - FZUOJ (fzoi.top) 先按距离排序,分块,块内按 m 排序。写一个类似 bfs 的东西,如果一个块的最大的 d ,即 d[r[i]] 都可以在范围内,那么只需要考虑 m 限制,从块头扫即可,注意块头应该修改,不然会被卡回 O(n^2)
- 线段树扫描线 20211030 军队 - Problem - FZUOJ (fzoi.top) 线段树维护区间数字具体出现次数,解决问题第一部分。求得每一行雌/雄个数,设 \(a[i]\) 为雌/雄个数的min。发现对于单个行选 y 个,答案最优为 \(\lfloor\frac y2\rfloor\times (y-\lfloor\frac y2\rfloor)\) ,预处理 \(cnt[i]\) 表示 a 大于等于 \(i\) 的数的个数,判断一下。若 \(a[i]<\lfloor\frac y2\rfloor\) ,列出选 \(x\) 行总和式子: \(\sum (y-a_i)a_i=y\sum a_i-\sum a_i^2\) 前缀和 \(a,a^2\) ,即可 \(O(1)\) 回答问题。
- 普通莫队 [P1972 SDOI2009]HH的项链 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 模板
- 可持久化线段树+单调栈 IOI 2015 Teams 分组 - Ameiyo - 博客园 (cnblogs.com)
- 李超线段树 [HEOI] Segments 模板
- 树链剖分+可持久化 Trie 树 https://www.luogu.com.cn/problem/P4592 RT
- 树上主席树数颜色 [SDOI2018] 原题识别 见题解
- BFS序+线段树[海亮NOIP集训]树[day6]ysy - 题目 - FZUOJ (fzoi.top) RT ,\(f[u][i]=f[f[u][i-1]][i-2]\) ,其中 \(f[u][1]=f[u][2]=1\) ,即斐波那契定义下的祖先
- 淀粉质 20211115 旅行 - 题目 - FZUOJ (fzoi.top) 考虑淀粉质,计算贡献时,标注一下这个点是属于分治重心的哪个子树,一个可贡献区间拆分成 L R 端点,按端点排序。记 \(cnt_i\) 表示子树 i 中可行区间数量。碰到一个 L,贡献+=当前所有可行区间-cnt_{L 所属区间} ,碰到一个 R, 对应子树 cnt 减少,当前可行区间个数减少。往下面继续分治即可
- 莫队区间众数出现次数 P3709 大爷的字符串题 RT
- 线段树优化BST建立/笛卡尔树 [TJOI2011] 树的序 RT
动态规划
-
线段树辅助DP PYB 的字符串 - 题目 - FZUOJ (fzoi.top) 在序列没有修改的时候,我们设 \(f[i][j][k]\) 表示原串前 i 个字符,匹配串的 [j,k] ,可以不连续地出现次数。有修改,线段树区间合并,\(f[i][j][k]=f[l][j][k]+f[r][j][k]+\sum f[l][j][h]\times f[r][h+1][k]\) \(l,r\) 表示左右区间。求答案时,合并这 \(log\) 个区间即可。
-
决策单调性 20211005 购票方案(VanishD day1) - 题目 - FZUOJ (fzoi.top) 容易得到方程,容易发现排序后存在决策单调性
-
正难则反 20211005 直线相交(VanishD day1) - 题目 - FZUOJ (fzoi.top) f_(i,j)表示当前考虑了前i根木棒(前i根木棒和后面的都不平行),是否可以构成j个交点。转移:枚举最后一组平行的木棒数量k。则有方程:
f_(i,j)=⋃_(k=1)^i f_(i-k,j-(i-k)×k) O(N^4)
逆向DP 考虑当前的方案与最多的交点数(即全部两两相交相差的数量)那么将所有的木棒分成k组,每组内部都是互相平行的。数量为:a_1,a_2,…,a_k g_i表示与全满的状态相差i个交点至少需要多少木棒:
$g_i=min_{j=1}^N(j+g_{i-j×(j-1)/2}) $
此时DP的时间复杂度为O(N3),考虑询问(N,M),他能完成当且仅当g_(N×(N-1)/2-M)≤N。总复杂度为O(N3+Q)
-
容斥 20211005 记录数列(VanishD day1) - 题目 - FZUOJ (fzoi.top) 令sum_i表示存在至少i个相邻的区间能合并成更大区间的方案数 ans=∑_(i=0)^N sum_i×(-1)^i
记 f_(i ,j,0 or 1) 表示考虑完第 i 段,存在至少 j 个相邻的段是可以接上的(即可以被看做一个更大的段),第 i 段序列是单调增的 0 还是单调减的 1。特殊处理 a[i]==1 的情况
-
数据结构+决策单调性优化dp 20211005 模式匹配(VanishD day1) - 题目 - FZUOJ (fzoi.top) 设 \(dp[i]\) 表示前 i 个字符可以构成的长度,\(dp[i]=max(dp[i-1],dp[k]+4)\) ,\(k\) 满足 s[k+1] 在区间 (pre[i],i] 中出现过。显然,k 越大,dp[k] 越大,决策单调性。考虑维护 k 的位置,考虑在从 1 遍历到 n 的过程中,维护 pre[] ,并把每一个 [pre[i],i] 在线段树上加上 i。线段树维护最大值,k 就是线段树在 pre[i]-1 的最大值对应的位置。特殊在于 aaaa 满足条件,需要跳一位再询问。
-
DP套DP [HDU 6968]I love exam - 题目 - FZUOJ (fzoi.top) 设 \(A[i][j]\) 表示第 i 门课,花费 j 天的最高提分,\(B[i][j][k]\) 表示前 i 门课,花费 j 天,挂掉 k 课,最高得分。 A 显然是一个背包,B 通过 A 转就可以了。在做 A 的同时,需要记录 \(cost[i]\) 表示第 i 门课不挂科的最少用时,以判无解
-
DP辅助DP [P7914 CSP-S 2021] 括号序列(民间数据) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) [CSP-S 2021] 括号序列 题解 - lost_heart_hurts - 博客园 (cnblogs.com)
-
状态结果交换 20211026 String - 题目 - FZUOJ (fzoi.top) 普通的,设 \(dp[i][j]\) 表示 \(a\) 匹配到 \(i\) 位,\(b\) 匹配到 \(j\) 位的最小步数,可以 \(O(|\sum|\ n^2)\) 解决问题,但是本题 \(n=5000\) ,需要干掉字符集。考虑设 \(f[i][j]\),\(i\) 表示长度 ,当前 \(a\) 串上匹配到 \(j\),\(b\) 串上匹配最多能到哪。 注意到出现最少的字母至多出现 \(n/26\) 次,所以答案不超过 \(n/13+1\)。所以暴力转移(每次 )复杂 度就是严格 \(O(n^2)\) 。
-
前缀和优化DP 20211102 多项式题(poly) - Problem - FZUOJ (fzoi.top) 设 \(dp[i]\) 表示在 \(i\) 和 \(i+1\) 之间截断,前面任意的答案。
-
斜率优化DP [CEOI2017]Building Bridges 李超线段树维护,见题解
-
**树形DP ** 20211106 集合 - 题目 - FZUOJ (fzoi.top) 设 \(B/F/C[x][k]\) 分别表示 \(x\) 子树内经过 \(k\) 个点(包含 \(x\) )的路径,起点终点都在 \(x\)/ 起点在\(x\) / 起点终点都不在 \(x\) ,转移即可(多画图!)
-
**数据结构优化 DP ** 序列(sequence) - 题目 - FZUOJ (fzoi.top)
-
高斯消元期望DP 【HNOI2013】游走 考虑把边经过次数的期望转成点经过次数期望,点期望列出方程后直接高斯消元求解
-
矩阵加速转移DP CF1151F 设 \(dp[i][j]\) 表示进行 \(i\) 次操作,最前面 \(m\) 个数中有 \(j\) 个 \(0\) 的方案数,其中 \(m\) 表示全局 \(0\) 的个数。那么答案即为 \(dp[n][m]/\sum dp[n][i]\) 。发现转移方程可以写成矩阵。
-
前缀和优化DP AGC009C ,不妨设 \(A>B\) ,那么无解情况就是 \(\exist a[i]-a[i-2]<B\)
设 \(dp[i]\) 表示做到位置 \(i\) , \(i\) 在 \(A\) 集合方案数,发现 \(j\) 若满足 \(\forall k\in[j+1,i],a[k]-a[k-1]\geq B\) 且 \(a[i]-a[j]\geq A\) 即可转移到 \(i\) ,发现这样的j在一段连续的区间。前缀和优化。最后用dp[i]计算出最终答案
-
容斥DP ARC101E Ribbons on Tree 设 \(f(S)\) 表示 \(s\) 集合中的边不染色方案数, \(g[i]\) 表示 \(i\) 个点两两配对染色方案数,F(S) 也很好计算, 显然 S 将原树分割成了若干个连通块, 我们只要把联通块大小对应的 g 值相乘就可以得到了,经过简单的容斥后可以得到 \(ans=\sum_{S\subseteq E}(-1)^{|S|}F(S)\) 。发现 \(f\) 的转移方式满足树形背包 DP 的形式,考虑设 \(dp[i][j]\) 表示在子树 i 内有 j 个点与 i 在同一个连通块的子树内匹配的方案数, 特别的, 令 \(dp[i][0]\) 表示子树 i 的点全部匹配的方案数,\(N^2\) 转移即可
-
交换答案状态 20211115 跑步 - 题目 - FZUOJ (fzoi.top) 省略
-
前缀最大值优化DP tree - 题目 - FZUOJ (fzoi.top) 首先小心可能直径不经过环。考虑在环上 DP ,发现一个点可能可以和前面的组合,可以和后面的组合,也可以换个方向绕一圈,容易发现可以前缀最大值优化。
计数
- 条件转化 [2021牛客提高第一场]与巨 - 题目 - FZUOJ (fzoi.top)
- 计数DP [P2051 AHOI2009]中国象棋 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 按行考虑,设 \(f[i][j][k]\) 表示前 \(i\) 行,\(j\) 列填了一个棋子,\(k\) 列填了两个棋子的方案数
- 计数DP+刷新 [P5456 THUPC2018]蛋糕 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 发现每个维度相对独立,且当且仅当当前维度坐标达到上/下界接触面增加1。设 \(dp[i][j]\) 表示前 i维,接触了j面的方案数,讨论维度上界是否为1即可。这里需要采用刷新的方式。
- 差分转化计数 [HDU 7055]Yiwen with Sqc - 题目 - FZUOJ (fzoi.top) 推狮子发现存在平方项,不好动态维护,考虑差分降次
- 树上计数 「NOIP2014」联合权值 - 题目 - FZUOJ (fzoi.top) 容易算出每一个中转点的贡献
- 条件转化+递推 基础计数练习题(perm) - 题目 - FZUOJ (fzoi.top) 发现 P>Q 和 P<Q 的方案数是相同的,那么 \(v[i]=\frac 12 (i!-f[i])\) ,其中 \(f[i]\) 表示 \(1\) 到 \(i\) 的排列,st,P=Q 的方案数。容易推得: \(f[i]=f[i-1]+(i-1)\times f[i-2]\) ,即形成 \(p_x=x\) 或者 \((p_x=y,p_y=x)\) 的二元组。
- 抽屉原理 CF850A Five Dimensional Points - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 发现五维坐标有 5 条坐标轴,然后知道每个坐标轴分 + and - 所以我们任意将一个点作为坐标原点,这样知道当 n > 34 时一共有 33 个其余的点。根据抽屉原理,这样就至少有一个象限分到两个点。然后如果真的有的话,那么无论如何当前这个坐标原点所对的点不能成为“好点”。根据抽屉原理,知道当 n > 34 时答案永远是 0。
- 计数DP ABC226F 见题解
- 图上计数 20211108 黑白树 - 题目 - FZUOJ (fzoi.top) 考虑把直径提出来,对于普通的树,到一个点最远的点一定是直径的端点之一,先求出一条直径,若直径的两个端点颜色相同, 则最长距离一定为直径,否则,令两个端点分别为 x, y,枚举答案 d,所有到 x 距离 > d 的点颜色必须与 y 一样,所有到 y 距离 > d 的点颜色必须和 x 一样,由于 x, y 是直径的两个端点,可以发现,若一个点 z 到 x, y 的距离都不超过 d,则其到任何一个点的距离不超过 d,所以 z 的黑白并不会对答案产生影响。 具体的,找出直径,预处理直径到每一个点的距离,从大到小枚举 d,维护当前没有被限制的点的个数, 当出现 min dis(x, i), dis(y, i) > d 时说明 d 已经不合法。
构造
-
分块 20210925 不等(pb day1) - 题目 - FZUOJ (fzoi.top) 如果没有 01 数量不相等的限制,那么直接令颜色等于 bitcount 的奇偶性即可。根据 \(\lceil \sqrt{n}\rceil\) 的提示,可以想到用分块的方式调整数量。可以找到这样一个函数: 把 \(n\) 分成 \(\sqrt n\) 块,那么一个 \(n\) 位二进制数的函数值是 1 ,当且仅当它至少一块全都是 1。我们让最后的颜色变成 奇偶性 \(\oplus\) 函数值,那么, 一个函数值是 0 的数只有 \(\sqrt n\) 块可能变成 1 ,每块都至多一种方案,所以函数值为 0 的数只有 \(\sqrt n\) 种方法会变化;而 一个函数值为 1 的数只有在只包含一块的情况下会变,此时这个块长也是 \(\sqrt n\)。
-
奇偶分析 CF550D Regular Bridge - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) •由于是无向图,所以子图的总度数应为偶数。所以n和k都是奇数 。由于每个点的度数为k,所以一张子图至少要k+1个点,但k+1奇偶性不对,所以我们考虑k+2个点。将完全图删去(1,2),(1,3),(4,5),(6,7),…,(k+1,k+2)即可。
-
贪心 [AGC010E] Rearranging 每个整数建一个点,不互质的连边。显然可以每个连通块求出答案后贪心合并。对于一个连通块,第一个数可以取最小的(记为x)。接下来考虑删去它之后的每个连通块,为了使x不被换到后面,每个连通块的第一个数必须是与x有连边的。同样每个连通块求出以后合并即可。
-
树分块 [SCOI2005] 王室联邦 一个有效的构造是,递归处理每个点,每次把当前节点假如栈中,对于扫过每个儿子,看现在栈中的点个数是否 \(\ge B\) ,是则分块。这样,子树中最多遗留 \(B-1\) 个点,和另外一个子树一起,算上父亲,最多 \(2B-1\) 个点。dfs 结束后,可能栈中还剩下 \(B-1\) 个点,假如根节点所在的块中,大小 \(\leq 3B\)