这周打了一场模拟赛,学了dsu on tree,线段树合并,点分治边分治&点分树,树套树,K-D Tree,STL中的bitset,分块&莫队学了好多东西。
模拟赛中犯了低级错误文件怎么能写错啊啊啊啊,于是唱歌自省。在模拟赛中也学到了东西:线段树可以维护最短路,折半搜索签到题没签出来,看起来数组开不下但实际要用的状态数很少的DP可以用map维护一下,巩固了一下xor hashing的trick。
这周对于树上问题处理的手段增加了很多。dsu on tree通过类似树剖的方式保证了\(O(n\log n)\)的时间复杂度,而又只保存重儿子的信息保证了\(O(n)\)的空间复杂度,很优秀而且好写。但是要注意在维护信息时也可以用set/map之类的容器辅助,不要太死扣\(O(n\log n)\)的时间复杂度,有时多只\(\log\)也可以。
淀粉质点分治边分治也是处理树上问题的利器,通过每次以当前树的重心作为分治中心来保证子树大小每次分治至少减半,于是时间复杂度\(O(n\log n)\)。点分树将点分治每次的分治中心保存下来构成树形结构,相当于将点分治离线下来,并且由于点分治的性质,树高是严格的\(\log n\)。点分树可以在线地回答询问,并且由于树高的性质,一些看上去复杂度不对的暴力在它上面就对了但暂时还没学懂。
对于线段树合并,感觉合并就像是相加,类似树上前缀和,可以在\(O(n\log n)\)的时间内合并信息。根据老师的例题,这个东西可以维护DP,但暂时还不会,据说这个东西叫整体DP。
树套树与K-D Tree是高级的数据结构,码量有些大并且暂时考不到,更加高深的部分暂时咕咕咕了K-D Tree可能暂时完全咕咕咕了。树套树目前大概会BIT套线段树,线段树套线段树但是后者还没正式写过,只是感觉与前者同理即可。具体做题时就要考虑好外层要维护什么,内层要维护什么,然后分别选择合适的数据结构,再套在一起。
bitset属于STL,做位运算的时间复杂度为\(O(\frac{n}{w})\),\(w\)根据环境不同分别有\(w=32\)和\(w=64\),总之是\(n\)带一个小于\(\frac{1}{10}\)的常数。一些关于bool的DP可以考虑用bitset优化,使时间复杂度正确。
分块&莫队时间复杂度都带根号,比较暴力,但可以解决很多很多问题只是可能时间不是特别优秀,而且有些特殊神秘的东西只能用这二者维护。最重要的是平衡思想,体现在可以用均值不等式求块长,以及可以根据不同的情况选择不同的暴力(很类似于根号分治),保证根号级别的复杂度。分块是一种优雅的暴力,好写好用。