给出 n 个数,Q次询问,每次问[l,r]中最大连续异或和。
为了体如今线操做,对于每次询问(x,y):
l=min( ((x+lastans) MOD n)+1 , ((y+lastans) MOD n)+1 )
r=max( ((x+lastans) MOD n)+1 , ((y+lastans) MOD n)+1 )
1.2 输入格式
第一行为两个整数n,m,分别表示数的个数和询问次数。
接下来一行 n 个数,再接下来 m 行,每行两个数 x,y,表示给出询问 (x,y) ,经过上述操做获得l和r,查询 [l,r] 中最大连续异或和。
1.3 输出格式
输出m行,每行一个整数表示该次询问的答案。
1.4 样例输入
3 3
1 4 3
0 1
0 1
4 3算法
1.5 样例输出
5
7
7
1.6 数据范围与约定
对于30%的数据,n <= 500, Q <= 500。
对于100%的数据,n <= 12000 , Q <= 6000 , 给出的数均在signed long int 范围内,且均为非负数。
-------------优化
强制在线,区间连续异或和,很明显的一道可持久化trie树。ast
枚举l,r,作个前缀异或和,暴力统计就好了,复杂度O(n^3)统计
考虑怎样就不用枚举r了,trie树,对吧!咱们能够先把每一个数加进trie里,而后从l到r贪心往下找就好。
复杂度O(n^2logn)数据
考虑优化上一个算法。咱们能够用可持久化trie树优化掉把元素加入trie的过程,好像也没好多少查询
继续优化上一个算法。既然已经能够查询[l,r]内与x异或最大数,咱们能够把全部答案全预处理出来。
O(n^2logn)警报
好吧,看来不能预处理这么多。那能不能先预处理一部分,再在询问中处理一部分?
这不就是分块的思想吗!!!
因而,咱们能够预处理出每一个块的左端点到它右边的全部区间的最大异或和。
设f[i][j]表示第i块的左端点,到j,也就是[(i-1)*len+1,j]的区间最大异或和。
转移方程就不用多说了。
因而,咱们在查询一个[l,r]时,答案能够来自两部分:起始点在l-1所在的块内,或者块外。
对于块内的状况,贪心去查trie树便可。
对于块外,用咱们预处理的f就行。
复杂度O(n^1.5log(maxlongint))枚举