前言
最近接触到了树分块(大三才接触到了QAQ),然后打算总结下……
普通莫队算法
简单回顾一下普通的莫队算法,莫队算法是用来解决区间询问的算法,其把区间分成 n√ 份,每份的大小是 n√ 。把所有询问按其左端点所在区间为第一关键字,右端点按第二关键字排序,然后依次移动左右指针,处理相关询问。算法的时间复杂度在于当前区间的左右指针移动。左指针每次只会在块内移动,复杂度为 O(q∗n√) ,因为相同块的询问的右指针是递增的,所以每块的右指针总共会移动n次,共有 n√ 块,所以右指针的复杂度是 O(n∗n√) 。总复杂度为 O(n∗n√) 。
静态树上莫队
cf上有个博客说的很清楚(虽然是英文)地址:http://codeforces.com/blog/entry/43230,博客的大意就是说通过dfs序,把一颗n个节点的树变成一个2 * n的dfs序数组,该数组下标是dfs序,内容是dfs序对应的树上的节点。然后通过判断(u, v)的lca,就可以判断出u到v的路径。
具体操作是:设in[x]为节点x的入度,out[x]为节点x的出度,令in[u] < in[v],如果u就是(u, v)的lca,那么这个路径就是dfs序数组的in[u]到in[v]的下标,如果u不是(u, v)的lca,那么这个路径是dfs数组的out[u]到in[v]的下标外加lca。
为什么?不为什么,这就是dfs序的性质。
复杂度 O(n∗n