Problem
给定一个非负整数序列 a{a}a,初始长度为 nnn。
有M个操作,有以下两种操作类型:
1、A1、A1、A $ x$:添加操作,表示在序列末尾添加一个数 xxx ,序列的长度 n+1n+1n+1。
2、Q2、Q2、Q $ l$ $ r$ $ x$:询问操作,你需要找到一个位置 ppp,满足 l<=p<=rl<=p<=rl<=p<=r,使得:
a[p]a[p]a[p] xorxorxor a[p+1]a[p+1]a[p+1] xorxorxor ......... xorxorxor a[N]a[N]a[N] xorxorxor xxx 最大,输出最大是多少。
Solution
可持久化字典树…
Code
#include <bits/stdc++.h>
#define N 600010
int n,m,tot=0,a[N],rt[N],sum,bin[30];
char op[5];
struct Node{int son[2],sz;}tree[N*30];
inline void ins(int &rt,int x){
tree[++tot]=tree[rt];rt=tot;
int p=tot;tree[p].sz++;
for(int i=23;i>=0;i--){
bool opt=x&bin[i];
tree[++tot]=tree[tree[p].son[opt]];
tree[p].son[opt]=tot;
p=tot;
tree[p].sz++;
}
}
inline int query(int p,int v,int x){
int ans=0;
for(int i=23;i>=0;i--){
bool opt=bin[i]&x;opt^=1;
if(tree[tree[v].son[opt]].sz-tree[tree[p].son[opt]].sz>=1)
ans|=bin[i],p=tree[p].son[opt],v=tree[v].son[opt];
else p=tree[p].son[opt^1],v=tree[v].son[opt^1];
}
return ans;
}
int main(){
// freopen("a.in","r",stdin);
scanf("%d%d",&n,&m);n++;
bin[0]=1;for(int i=1;i<=23;i++) bin[i]=bin[i-1]<<1;
ins(rt[1],0);
for(int i=2;i<=n;i++){
scanf("%d",&a[i]);
sum^=a[i];rt[i]=rt[i-1];
ins(rt[i],sum);
}
while(m--){
scanf("%s",op+1);
if(op[1]=='A'){
int x;scanf("%d",&x);
sum^=x;n++;
rt[n]=rt[n-1];
ins(rt[n],sum);
}else{
int l,r,x;scanf("%d%d%d",&l,&r,&x);
printf("%d\n",query(rt[l-1],rt[r],x^sum));
}
}
return 0;
}