神奇的根号--莫队算法

神奇的根号–莫队算法


莫队这个根号我觉得是比分块灵活的,就在于他有许多的方式


0.先决条件

莫队的先决条件,在我看来就是两个
1:可以从区间[l,r]快速转移到[l,r+1][l,r1][l+1,r][l1,r]
2:时间允许O(nsqrt(n))

1.普通莫队

简单莫队 。
因为我们可以发现我们从[l,r]转移到[l1,r1]的次数是abs(l1l)+abs(r1r),像极了曼哈顿距离,所以我们把每一个关于区间的询问抽象成二维平面上的点,然后用根号为块的大小进行询问的划分(证明网上一大堆),因为每次改变左、右端点是O(1)这样我们就可以简单期望效率是O(nsqrt(n))
板子题也是一大堆,这里不列举

2.带修莫队

不是那么简单的莫队。
考虑当我们的操作加入了修改?我们应该怎么办?
修改操作是不和谐的,因为修改相当于是在本来的二维平面上强行有添加了一个维度,所以我们只有给每个询问或者秀改操作加上时间标记,当我们执行修改的事就就可以跳到当前我们的时间,这样我们就可以进行维护了,但是我们发现在这种情况下块的大小不是最优的,所以我们把块的大小调整为n2/3
这里给出复杂度为n5/3的简单证明:
当左右端点所在块不变时,询问是按时间排序的,因此询问的时间不降,所以时间指针只会向后移动n步,而左右两端点改变时时间指针最坏情况下会一次向前移动n步。而由于左右两端点所在块的种类组合起来只有n2/3种,且每种组合中,时间指针只会向后移动n步;取值改变也只有n2/3次,时间指针每次向前移动n步,时间指针的总复杂度即为n5/3
左右端点所在块不变时,右指针一次移动最多n2/3步,由于有n次询问,所以这里的复杂度不超过n5/3 。而当左端点所在块不变,右端点所在块改变时,右指针就不会往回移动到前一个块中,因此左端点所在块不变,由于右端点所在块改变所带来的的移动的复杂度不超过n,而总共有n1/3种左端点所在块取值,所以这里的复杂度不超过n4/3,而当左端点所在块改变时,右指针最坏是一次移动n步,与之前类似,总共有n1/3种左端点所在块取值,所以这里的复杂度不超过n4/3。右指针总时间复杂度为n5/3
左端点所在块不变时,左指针一次移动最多n2/3步,由于有n次询问,所以这里的复杂度不超过n5/3 。当左端点所在块改变时,由于排序是按左端点所在块为第一关键字,所以之后左指针就不会移动回前一个块,因此这种情况下的左指针移动带来的总复杂度不超过n,左指针总时间复杂度也为n5/3
综上,这个拓展的做法的总时间复杂度即为n5/3

模板:BZOJ2120


3.树上莫队

建成树的莫队。
有时我们所处理的问题并不为序列上的区间问题,而是树上的路径。那么实际上我们也可以把莫队算法拓展到树上,即树上莫队。
核心思想依旧没变,因此我们需要考虑的仍是如何将询问排序。而常用方法则是将树上的点标号,使其变为序列,然后用普通的莫队算法解决。
解决时唯一不同的则是原来序列上用的是左右指针移动,现在树上这个方法不太好用,因为左边或右边可能都与当前位置节点不相邻,并不是我们需要维护的路径上的东西。
所以我们应该怎么办?
观察后可以发现:
而从(u1,v1)转移到(u2,v2) 我们需要把(u1,u2)路径上除了lca(u1,u2)之外的点在答案中的状态取反,把(v1,v2)路径上除了lca(v1,v2)之外的点在答案中的状态取反。通过画图或者简单推导我们能现在,这么做后,剩下的在答案中的点,都在(u2,v2)它们之间的除去lca之外的路径上。
复杂度证明真不会,可以参见vfk博客中的证明。

对点进行标号的方法一般有两种:
1.我们DFS 这棵树,同时记录下它们的入栈出栈序,对这个序列进行分块
2.对树分块(对树进行DFS,每个点出栈后将其放进队列,当队列里的点超过B 个时将这些点分为一块)

个人偏爱第二种

模板题BZOJ3052,树上带修莫队,代码丢失了。。。。

//qwq

4.回滚莫队

科技莫队。
跟yyf大佬学的。dalao blog
在莫队转移过程中,如果我们发现删除操作不好进行,那么我们就可以用回滚莫队技巧来回避掉删除操作
我们在左端点blocki中的所有讯问,容易发现右端点是单调不减的,所以我们可以每次都把左端点从blocki的右端点向前跑,然后右端点直接向后跑就可以了。注意在这里先跑右端点记录下左端点在blocki的右端点的答案方便后面的计算。
然后考虑特殊情况,如果一个询问左右端点在同一区间,暴力跑过去就好了,时间效率上限是块的大小。如果一个询问左端点所在的块不等于上一个询问的左端点所在块,即进入了一个新的块,我们直接从这个询问的l跑到r记录答案就好了,单次O(n),因为块数为sqrt(n),所以时间上线还是O(nsqrt(n))

模板题直接看今天的考试题好了。。
或者BZOJ4241也行

posted @ 2018-07-03 22:09  Dream_maker_yk  阅读(350)  评论(0编辑  收藏  举报