Problem
给定一个非负整数序列
a
{a}
a,初始长度为
n
n
n。
有M个操作,有以下两种操作类型:
1
、
A
1、A
1、A $ x$:添加操作,表示在序列末尾添加一个数
x
x
x ,序列的长度
n
+
1
n+1
n+1。
2
、
Q
2、Q
2、Q $ l$ $ r$ $ x$:询问操作,你需要找到一个位置
p
p
p,满足
l
<
=
p
<
=
r
l<=p<=r
l<=p<=r,使得:
a
[
p
]
a[p]
a[p]
x
o
r
xor
xor
a
[
p
+
1
]
a[p+1]
a[p+1]
x
o
r
xor
xor
.
.
.
...
...
x
o
r
xor
xor
a
[
N
]
a[N]
a[N]
x
o
r
xor
xor
x
x
x 最大,输出最大是多少。
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;
}