近一周的时间内进行了数据结构的复习,在此对知识方面和一些常用技巧进行总结。
并查集:
按秩合并:按照树高小的往大的里面合并,使树高<=logn。
保留树的形态,使可以通过查询lca等操作得到两个元素第一次连通的时间。亦可以通过栈存储使其变为可撤销并查集。
路径压缩:除了根外,也可以维护其他与根相关的信息,如与根的值之差(实际上是与fa有关的信息,在getfa中一并更新到根)
一些优化和技巧:
1.使用类似st表的方式维护,省去多余的合并。
2. 启发式合并。
3. 拆点。例:bzoj1370,确保敌人的敌人是朋友。
4. 维护一些区间信息,给出一些和(转化为差)判断是否有矛盾,以及使点不重复的连续区间相连。例:bzoj1202
待续。
线段树 & 主席树:
这周学习了李超线段树。
一些优化和技巧:
1.动态开点,线段树是可以开很大的范围的。与操作次数有关
2.主席树的坐标往往是时间为x坐标,但也可以以值域为x坐标,维护其他东西。例:bzoj2653
3.主席树可以维护区间的静态信息,例如查询区间内出现次数刚好等于自身的数有几个/和,可以通过以区间右端点为x坐标,存储类似前/后缀和的东西。
树状数组:
相比线段树常数较小,常常在cdq分治中应用。一般来说支持单点修改+区间查询 维护前缀和,也可以用差分思想存储区间信息,进行区间加等操作。dalao的博客
然后还有二维树状数组。
平衡树:
我现在只会写splay了…
和线段树相似,可以维护诸多区间信息,例如hash值,最大最小值。维修数列一题比较全。
例:bzoj1014
左偏树:
常常和并查集一并使用,这种时候要注意弹出的堆顶的fa依然要指向新堆顶。
链表:
相当常用的类似链式前向星的存储方式,合并也很方便。
理不清可以自己画图理解。
例:bzoj1483
set :从此不写平衡树系列。
一些优化和技巧及注意事项:
1.先插入+-inf作为边界。
2.通过tmp= * –find(x) tmp= * ++find(x) 访问前后驱
3.自定义比较函数。
4.启发式合并
heap:
自带的stl,相当方便,默认是大根堆,末尾加 greater< int >( )变为小根堆。
h[t]=x;
push_heap(a,a+(++t));
pop_heap(a,a+(t–));
其他:
观察是否有单调性,可以考虑维护单调队列或单调栈。
很多数据结构都可以启发式合并。
前缀和 和 差分 的思想很常用。
关于之后的计划:
目前感觉栈,队列一类触及到的比较少,就夹杂在其中复习。
国庆穿插地复习数论和DP(背包和各种优化DP)
沈阳题表上的分类比较细,应该能全面过一遍。
数论部分先捡知识,忘了的crt,ind,元根等。
复xue习xi 01分数规划。
看组合数学。