关于一些莫队的总结

关于一些莫队的总结

最近学了一些莫队的应用,先总结如下。

1.一类莫队的优化

对于某一些莫队,当它的修改操作复杂度较高,又具有可差分的性质时,我们可以考虑如下优化方法————给莫队询问操作对应的修改操作“二次离线”。具体来说,设当前左右指针为nl,nr,现在的询问左右指针为ql,qr,有:

$1.ql \lt nl:delta=\sum_{i=ql}^{nl-1} Ans([1,r],i)-\sum_{i=ql}^{nl-1} Ans([1,i],i) $

\(2.ql \gt nl:-delta=\sum_{i=nl}^{ql-1} Ans([1,r],i)-\sum_{i=nl}^{ql-1} Ans([1,i],i)\)

\(3.qr \lt nr:-delta=\sum_{i=qr+1}^{nr} Ans([1,i-1],i)-\sum_{i=qr+1}^{nr} Ans([1,l-1],i)\)

\(4.qr \gt nr:delta=\sum_{i=nr+1}^{qr} Ans([1,i-1],i)-\sum_{i=nr+1}^{qr} Ans([1,l-1],i)\)

对于每个式子只与边界的部分,可以前缀和预处理,然后\(O(1)\)查询,对于另外一部分,考虑离线,可以开邻接表挂在对应的nl-1或nr下面,然后预处理从左往右扫一遍即可。最后维护询问区间的答案时就可以\(O(1)\)移动指针,这样做当修改操作复杂度小于\(O(\sqrt{n})\)时,往往能够给总时间复杂度优化掉一个修改的复杂度,一个例子是Luogu 第十四分块(前体),就可以优化掉每一次将数插入桶中的\(O(3432)\)

2.树上莫队

首先肯定是先用dfs序将树转化为序列,dfs序的选择视不同的询问而定。比如询问子树,就使用普通的入栈dfs序,而询问树上路径则使用入栈出栈欧拉序(这样一条路径就对应序列上的一段,只是要特判\(lca\),修改暴力即可)。现在考虑如何分块,有两种分块方式,看个人喜好吧,这里两种都说一说:
1.就使用序列上的那一套,将dfs序分为\(\sqrt{n}\)块,在将询问按所在块端点排序即可(可能跑的要慢一点,但是时间复杂度是对的)。
2.考虑树分块(这个应该属于有保证的方法),具体可以参考[SCOI2005]王室联邦,将树分为\((\sqrt{n})\)。现在对于询问考虑左端点按所在树块,右端点按dfs序排序即可。
一道不带修改的树上莫队SP10707 COT2 - Count on a tree II
那么带修改树上莫队呢?就是把时间加做第三关键字,同时改分块大小为\({n}^{\frac{2}{3}}\)即可,对于时间轴上的修改暴力即可,复杂度是\(O(n^{\frac{5}{3}})\),这里有一道例题糖果公园

posted @ 2019-03-28 21:46  pkh68  阅读(146)  评论(0编辑  收藏  举报