Noip前的大抱佛脚----数据结构
Posted xzyxzy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Noip前的大抱佛脚----数据结构相关的知识,希望对你有一定的参考价值。
数据结构
线段树
注意:空间开4倍
神奇标记
From8.26 Test_zsy(CPU监控)
如果一个点权为(val)的点被打上了((a,b))标记,那么他的实际点权为(max(a+val,b))
干啥滴?
标记不下放
- 区间加标记不下放,维护区间max或者最大值
方法是当前(tag)维护当前区域标记,(t)维护左右儿子的(max+tag[now]),并没有快多少,如果仍然忘记见提交记录
并查集
维护二分图
并查集每个点维护是否要改颜色,然后按秩合并/按大小合并即可
实际上可以说是用期望树高为(logn)的树形结构维护信息
维护后继位置
快速得到后继位置
[BZOJ2054]疯狂的馒头 维护数列的后继位置
对一个数列进行(10^7)次区间覆盖,查询最终颜色。
倒序做,每次做完一个区间把([l,r])的并查集父亲指向(r+1),表示扫到该区间,要从(r+1)开始染色,这样就可以快速得到下一个染色的位置,复杂度为(O(n))
[BZOJ2238]Mst 维护树形结构的后继位置
对树上路径进行染色,查询最终颜色。
路径拆成直上直下的两条,(x,lca、y,lca),于是每次弄完把([x,lca])的并查集父亲指向(fa[lca]),就可以类似数列一样快速求得下一个位置了,复杂度为(O(n))
堆
对于所有的父子结构,一定都有父亲的优先级大于左右儿子的优先级
可并堆的可持久化
左偏树可持久化,每次合并两个堆,只需要给经过的(log)个结点复制一遍就好了
#define lc H[x].ch[0]
#define rc H[x].ch[1]
struct heap {int ch[2],dis;double w;}H[M];
int Merge(int x,int y)
{
if(!x||!y) return x+y;
H[++node]=H[x];x=node;
if(H[x].w>H[y].w) swap(x,y);
rc=Merge(rc,y);
if(H[lc].dis<H[rc].dis) swap(lc,rc);
H[x].dis=H[rc].dis+1;
return x;
}
这个可以用来完成(k)短路问题
dsu on tree
姑且叫它数据结构
方式&原理
步骤:
- 先递归做轻儿子的答案,再递归做重儿子的答案
- 暴力把当前结点的轻儿子扫一遍统计答案
- 如果当前结点是递归下来的轻儿子,扫一遍把答案清空,否则不做处理
要求: 离线算法
复杂度: (O(nlogn))
分析:只需要考虑每个点被扫的次数,树剖下来每个点到根的路径最多有(log)条链,每逢轻重链交替的时候就会暴力去扫,于是每个点最多只会被扫(log)次,复杂度得证
适用范围
适用一些子树信息不好统计的题,可以类比于树上莫队
统计子树内数量最多的颜色的编号之和(Codeforces600E)
统计子树内距离(i)点不超过(k)的点的颜色数/某权值之和(BZOJ4771七彩树离线版/[湖南集训]谈笑风生)
?
以上是关于Noip前的大抱佛脚----数据结构的主要内容,如果未能解决你的问题,请参考以下文章