# BZOJ2741 【FOTILE模拟赛】L 【可持久化trie + 分块】

## 题目

FOTILE得到了一个长为N的序列A，为了拯救地球，他希望知道某些区间内的最大的连续XOR和。

l = min ( ((x+lastans) mod N)+1 , ((y+lastans) mod N)+1 ).
r = max ( ((x+lastans) mod N)+1 , ((y+lastans) mod N)+1 ).

3 3

1 4 3

0 1

0 1

4 3

5

7

7

## 提示

HINT

N=12000，M=6000，x,y,Ai在signed longint范围内。

## 题解

【坑点，给出的x，y可能超过int范围】

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define LL long long int
using namespace std;
const int maxn = 12005,Bit = 31,maxm = 6000000,INF = 100000000;
LL out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
LL n,m,A[maxn],sum[maxn],bin[40];
LL f[200][maxn],block[maxn],B,lans;
struct trie{
int ch[maxm][2],sum[maxm],rt[maxn],cnt;
int ins(int pre,int x){
int tmp,u;
tmp = u = ++cnt;
for (int i = Bit; i >= 0; i--){
ch[u][0] = ch[pre][0];
ch[u][1] = ch[pre][1];
sum[u] = sum[pre] + 1;
LL t = x & bin[i]; t >>= i;
pre = ch[pre][t];
u = ch[u][t] = ++cnt;
}
sum[u] = sum[pre] + 1;
return tmp;
}
LL query(int u,int v,int x,int dep){
if (dep < 0) return 0;
LL t = x & bin[dep]; t >>= dep;
if (sum[ch[u][t ^ 1]] - sum[ch[v][t ^ 1]])
return bin[dep] + query(ch[u][t ^ 1],ch[v][t ^ 1],x,dep - 1);
return query(ch[u][t],ch[v][t],x,dep - 1);
}
}T;
int main(){
bin[0] = 1; for (int i = 1; i <= Bit; i++) bin[i] = bin[i - 1] << 1;
n++;
for (int i = 2; i <= n; i++) A[i] = read();
for (int i = 1; i <= n; i++){
sum[i] = sum[i - 1] ^ A[i];
T.rt[i] = T.ins(T.rt[i - 1],sum[i]);
block[i] = i / B;
}
for (int i = 1; i <= n; i++){
if (i == 1 || block[i] != block[i - 1]){
int b = block[i];
for (int j = i; j <= n; j++){
f[b][j] = max(f[b][j - 1],T.query(T.rt[j - 1],T.rt[i - 1],sum[j],Bit));
}
}
}
n--;
LL l,r,x,y;
while (m--){
l = min (((x + lans) % n) + 1, ((y + lans) % n) + 1);
r = max (((x + lans) % n) + 1, ((y + lans) % n) + 1) + 1;
lans = 0;
if (block[l] != block[r]) lans = f[block[l] + 1][r];
for (int i = l; block[i] == block[l] && i < r; i++){
lans = max(lans,T.query(T.rt[r],T.rt[i],sum[i],Bit));
}
printf("%lld\n",lans);
}
return 0;
}


posted @ 2018-04-03 21:17  Mychael  阅读(150)  评论(0编辑  收藏  举报