莫队算法学习小记

前言

我还是太弱了samjia都打出树上莫队了我还没打过序列上的莫队算法。一定是我对GDKOI2014的题目没有钻研导致我很长一段时间都没有接触莫队算法。
莫队算法可以使用,通常符合以下特点:1、允许离线。2、进行区间询问,并且我们已知区间l~r的答案,可以得到l-1~r或l+1~r或l~r-1或l~r+1这四个区间的答案。3、没有修改操作。

序列上的莫队算法

莫队算法改变了询问的顺序。
我们对原序列进行分块,以n^0.5为一块。然后对询问进行排序。第一关键字为询问左端点所位于的块,第二关键字位询问右端点。然后,我们只要按排序后的顺序做就可以了。当前已知l~r的答案,现在要得到l’~r’的答案,直接暴力转移即可。如何证明其复杂度位n^1.5呢?
我们观察,同一块内右端点是单调的,因此每一块内右端点的移动最多为o(n),一共n^0.5块则这部分复杂度为o(n^1.5)。
同一块内左端点每次变化最多为n^0.5,那么一共有n^0.5次变化,则复杂度最多为o(n),一共n^0.5块则这部分复杂度为o(n^1.5)。
在不同块的两个询问左端点和右端点最多变化o(n),一共有n^0.5次两个询问位于不同块则这部分复杂度为o(n^1.5)。
证毕。
例题:GDKOI2014小纪的作业题。

树上莫队

如何解决树上莫队问题?
我们可以对树求出括号序,fi[x]表示x第一次出现的位置,la[x]表示x第二次出现的位置。那么对于要求j到k的路径(fi[j] < fi[k]),分两种情况。
一:fi[k] < la[j],则此时j是k的祖先,括号序中的区间fi[j]~fi[k]即为对应询问区间。
二:fi[k]>la[j],此时括号序中的区间la[j]~fi[k]即为对应询问区间,注意这个区间包含不了它们的lca,还需要把lca丢进去。
如果一个点在区间内出现两次怎么办?
比如34421123,3到2的路径对应区间为3442,4出现了两次。
可以知道,出现两次的点不在对应路径上。
我们用bz[i]表示i点的出现情况,那么每次遇到一个点,就改变其出现状态即可。
于是就转化为普通莫队问题。
例题:苹果树

你可能感兴趣的:(莫队算法学习小记)