省选前复习小记
还有三天复习,而这只蒟蒻还在不知死活的颓废
数据结构小记
\(KD\)-\(Tree\)
- 基础功能:
- 领域查询(类似于启发式搜索,时间复杂度实际上没有保证)
- 维护高维空间数点,(此处以\(2\)维为例),可以进行,矩阵/单点修改,矩阵/单点查询....(反正就是一颗平衡树)
- 不是\(leafy\ tree\),每个点都代表实际上的一个节点和一个子空间,树高为\(O(\log n)\)
- 建树的时候根据\(x\),\(y\)的方差哪个大,决定按哪一维排序,并且尽可能地选择中位数作为根,使得子树尽可能均匀来保证树高
- 如果要求支持动态插入\删除的话,采用替罪羊树的暴力重构法,设一个阈值\(\alpha\)
if(max(siz[lc[u]],siz[rc[u]])) >= alpha * siz[u]
then rebuild(u)
- \(\alpha\)可以取值\(0.725\)
- 练习:[国家集训队]JZPFAR(\(\checkmark\))
- 本来是玄学复杂度的估价函数,然后因为保证数据随机就对了(大雾)
- 最小值的估价函数
double F(int a,int b){/*a到b区域欧式距离的估价*/
double res = 0;
if(t[a].x < L[b]) res += (L[b] - t[a].x) * (L[b] - t[a].x);
if(t[a].x > R[b]) res += (R[b] - t[a].x) * (R[b] - t[a].x);
if(t[a].y < D[b]) res += (D[b] - t[a].y) * (D[b] - t[a].y);
if(t[a].y > U[b]) res += (U[b] - t[a].y) * (U[b] - t[a].y);
return res;
}
- 最大值的估价函数
ll f(int a,int b){
ll ret = 0;
ret += max(s(t[a].x - L[b]),s(t[a].x - R[b]));
ret += max(s(t[a].y - D[b]),s(t[a].y - U[b]));
return ret;
}
- 需要注意一点,\(KD\)-\(Tree\)在建树后的点的下标会改变,如果需要用到原来的下标,需要提前标记
\(splay,LCT\)
\(kruskal\)重构树,笛卡尔树,可并堆(左偏树)
- 之所以把这几个归在一起是因为
我都不太熟悉,貌似都和最值有关 - \(kruskal\)重构树常用来解决瓶颈点\瓶颈路相关问题
- 瓶颈边的做法大家应该都很熟悉,按权值从小到大排序的合并建出来的是大根堆,反之是小根堆,这样的一棵树一共有\(n + m\)个点,叶子代表点,非叶节点代表边
- 这里讲一下瓶颈点的做法,按\(jiangly\)鸽鸽的话来说一点差别都没有(不过我可不这么觉得),其实就是按点权从小到大排序,然后向外连边,假设当前点是\(x\),我们只连\((x,y) \in E \&\& v_x \ge v_y\)的边,我们直接连\(y\)所在的并查集(可以理解为重构树的一个子树)所代表的根,并把它们合并起来
- 应用则是比较单一的,主要是利用了一个性质,此处以大根堆瓶颈边为例,若你当前在\(x\),则你能通过权值不超过v的边到达的点都在你重构树中最上面的权值\(\leq v\)的祖先的子树中
- 笛卡尔树则主要和最值分治以及一些性质题有关
- 重点复习左偏树
线段树分治,整体二分,树套树,\(cdq\)分治
线性基,\(bitset\)
- 线性基基础操作就不说了
- 静态区间线性基
- 维护前缀线性基,然后同时维护一个时间,在插入的时候尽可能使时间最大即可,具体地,在遍历到某一位时,我们保留时间较大的那一个,并把时间小的往下传
- \(k\)小值
- 如果要求\(k\)小值,我们可以让线性基的每一位互不影响,具体表现为,如果第\(i\)位线性基有值,那么我们就将其他第\(i\)位线性基上有值的数异或掉这一位,只要从大到小操作即可
void rebuild(){
for (int i=60;i>=0;i--)
for (int j=i-1;j>=0;j--)
if (d[i]&(1LL<<j))
d[i]^=d[j];
for (int i=0;i<=60;i++)
if (d[i])
p[cnt++]=d[i];
}
long long kthquery(long long k){
int ret=0;
if (k>=(1LL<<cnt))
return -1;
for (int i=60;i>=0;i--)
if (k&(1LL<<i))
ret^=p[i];
return ret;
}
- 习题:CF1299D Around the World(\(\checkmark\))
- \(bitset\)
- 基础操作熟悉一下,常用分块来压缩空间
- 习题:CF914F Substrings in a String(\(\checkmark\))
可持久化数据结构
线段树进阶操作
贪心\(dp\)小记
斜率优化注意点
dp凸优化
- CF125E MST Company(\(\checkmark\))
- 一个细节问题,凸包中有可能有若干个点斜率相同,以下凸壳为例那么我们需要保证在解最优的前提下,横坐标尽可能小,这样就可以保证答案是一定是当前点或在当前的点的右边,意味着要增大斜率这样可以方便二分
- 初始斜率的\(l,r\)要赋到上界
决策单调性
- 可以打表观察一下决策点数组
- 分治(在一些转移不依赖前面的值的时候可以
用) - 二分栈(应用比较广)
- 习题: [POI2011]Lightning Conductor(\(\checkmark\))
- NOI2011嘉年华(\(\checkmark\))
贪心模拟费用流
- NOI2019序列复习(\(\checkmark\))
- PA2013Raper(\(\checkmark\))
- [NEERC2016]Mole Tunnels
- 本质是模拟\(EK\)或消圈算法,在增广路很少且有特点的时候,直接用堆维护最短路
*保序回归和拟阵
计算几何学习
杂项
闵可夫斯基凸包和(包含极角排序和凸包)
- JSOI2018战争(\(\checkmark\))
- 注意原点的选择
for(int i = 1; i <= n; ++i){
if(p[i].x < p[1].x || (p[i].x == p[1].x && p[i].y < p[1].y)){
swap(p[i],p[1]);
}
}
- 选择\(x\)最小的点
*半平面交
*最小圆覆盖
- 模板最小圆覆盖(\(\checkmark\))
- 随机增量法的运用,设当前圆为\(C\),每次添加一个点\(p_i\),有以下事实
- 新的最小覆盖圆是
- \(if(p_i \in C)\ C\)
- \(otherwise\) \(C \cup {p}\)
for(int i = 1; i <= n; ++i){
if(!in(p[i],C)){
C = Cir(p[i],0);
for(int j = 1; j <= i - 1; ++j){
if(!in(p[j],C)){
C = Cir((p[i] + p[j]) * 0.5,0.5 * (p[i] - p[j]).dist());
for(int k = 1; k <= j - 1; ++k){
if(!in(p[k],C)){
C = calc(p[i],p[j],p[k]);/*求外接圆*/
}
}
}
}
}
}
网络流/二分图
\(Dilworth\ theorm\)
- 偏序集的最小不可重链覆盖等于最长反链
一些对偶结论
- 二分图的最小点覆盖 = 最大匹配 = 总点数 - 最大独立集
- 二分图最小顶标和等于最大带权匹配
\(DAG\)最小链覆盖
- 若不可重,拆点二分图:将一个点拆为出点和入点,若原图中有边,则从对应出点连向对应入点,最小链覆盖即为总点数-最大匹配
- 若可重,\(floyd\)传递闭包,转化成不可重问题
\(Hall\ theorm\)
二分图匹配
- 可以利用匈牙利算法
- 注意其本质是一个贪心的不停找增广路的过程
- 利用这一性质,我们可以解决这样一个问题,在满足最大匹配的前提下,能否令(x,y) 匹配
- 我们随意跑一个匹配,若\(match[y] = x\)显然可以,否则我们强行令\(match[y]:=x\),把\(x,y\)从二分图中删掉,然后令原来的\(match[y]\)重新跑一遍增广路(注意此时\(y\)已经不存在了),若其仍然能跑出增广路,则可以
- 更加一般地,我们可以直接把\((x,y)\)删掉然后继续规划,从而在保证最大匹配的前提下尽可能匹配我们想要的
- \(example:\)求二分图(保证有完美匹配)的字典序最小匹配
最小割
- 最小割的可行边与必须边
- 不妨考虑边\((x,y)\)
- 首先跑一遍最大流
- 可行边:该边满流且两端点在残量网络中不属于同一个强连通分量(\(scc\))
- 很好理解,注意若满流则残量网络存在反向边\((y,x)\),若\(x,y\)在一个\(scc\)内则意味着\(x\)还能到\(y\)那么就白割了
- 必须边:满流且\(x与S\)在同一个\(scc\)内且\(y\)与\(T\)在一个\(scc\)内
- 证明是平凡的,若不割,\(S->x->y->T\),矛盾
- 最小割模型构建网络流一些常用模型的建构
费用流
上下界网络流
- 无源汇上下界可行流
- 我们先强制每条边都流了下界,然后把上界减下界作为流量,计算每个点的流入量-流出量,记为\(M\),若\(M < 0\),则连向汇点,否则连向源点
- 计算每条\(S\)出发的边是否满流即可
- 有源汇上下界可行流
- 从\(T\)向\(S\)连\(inf\)的边即转化成上面的问题
- 有源汇上下界最大流/最小流
- 有源汇上下界最小费用可行流
- 模板|AHOI2014支线剧情(\(\checkmark\))
字符串
\(kmp\)与\(border\)
\(pam\)与\(manacher\)
\(AC\)自动机
\(sam\)和广义\(sam\)
数论
同余理论复习
- WC2021斐波那契
- \(BSGS,exBSGS\)(\(\checkmark\))
- 模板exBSGS
- 拓展欧拉定理(\(\checkmark\))
积性函数筛法
- \(powerful\ number\)(\(\checkmark\))
- 模板min25筛(\(\checkmark\))
迪利克雷卷积与莫比乌斯反演
组合数学及数学杂项
- (复习为主)
容斥原理
- ZJOI2016小星星(\(\checkmark\))
各种反演
- \(minmax\)反演
- minmax容斥学习笔记
- 拓展:
- \(E(kthmax(S)) = \sum_{T \subseteq S}Emin(T)\binom{|T|-1}{k-1} * (-1)^{|T| - k}\)
- 子集反演
- WC2019数树题解
- 二项式反演
- 单位根反演
- 拉格朗日反演
- 拓展拉格朗日反演学习笔记
斯特林数
- 第一二类斯特林数公式及组合意义
卡特兰数
生成函数
- \(PGF\):[SDOI2017硬币游戏复习]
- 解析组合学习笔记