猫树
解决无修改序列区间查询问题。预处理(O(nlog n)),询问(O(1)),空间复杂度(O(nlog n))(假设合并信息复杂度为(O(1)))。
将原序列长度扩展成(2^n),用堆式存储((rt)的左(右)儿子为(rt*2+0(1)))建一棵线段树。记(pos[p])表示表示(p)位置的叶子节点下标。
区间([l,r])对应的节点,即(pos[l],pos[r])的(LCA),由堆式存储的性质可以直接用(pos[l],pos[r])二进制表示的(LCP)求得,即pos[l]>>Log2(pos[l]^pos[y])
或pos[l]/(pos[l]^pos[r])
(深度即节点下标取(log_2))。
然后对每个节点([l,r]),可以像分治一样处理过(mid)的答案。然后就可以以(O(合并信息))的复杂度查询一次啦。
so猫树的本质就是将离线分治过程预处理出来(可以解决强制在线问题)。
不过在简单题里,和RMQ相比我好像...看不出区别... 难的题又不会做,所以,就不写代码了,随便记记。
猫树的数组可以用(val[mxdep][N])表示。
例题
NAND
给出一个序列,多次询问某个数(x)对给定区间中所有数按顺序依次NAND(与非)的结果。
按位处理,然后每个节点预处理区间中每个位置该位为(0/1)时到(mid)会变成什么。询问(O(1))合并。