Description
给定一个非负整数序列 ({a}),初始长度为 (n)。
有 (m) 个操作,有以下两种操作类型:
A x
:添加操作,表示在序列末尾添加一个数 (x),序列的长度 (n+1)。Q l r x
:询问操作,你需要找到一个位置 (p),满足 (l le p le r),使得: $
a[p] oplus a[p+1] oplus ... oplus a[N] oplus x$ 最大,输出最大是多少。
Solution
即求 (s[p-1] oplus (sum oplus x)) 的最大值,很容易想到可持久化 0-1 Trie
有点卡常
#include <bits/stdc++.h>
using namespace std;
const int N = 15000005;
const int lgn = 23;
int ind;
int ch[N][2],siz[N],head[N];
int n,m,a[N],s[N],t1,t2,t3,sum;
char op[3];
void insert(int x) {
//cout<<"insert "<<x<<" by "<<n<<endl;
head[n]=++ind;
int p=ind,q=head[n-1];
ch[p][0]=ch[q][0];
ch[p][1]=ch[q][1];
siz[p]=siz[q]+1;
//cout<<p<<","<<q<<endl;
for(int i=lgn;i>=0;--i) {
int t=(x>>i)&1;
ch[p][t]=++ind;
p=ind;
q=ch[q][t];
ch[p][0]=ch[q][0];
ch[p][1]=ch[q][1];
siz[p]=siz[q]+1;
//cout<<p<<","<<q<<endl;
}
}
int query(int l,int r,int x) {
//cout<<"query "<<l<<","<<r<<" "<<x<<endl;
int p=head[r-1],q=l>1?head[l-2]:0;
int ans=0;
for(int i=lgn;i>=0;--i) {
int t=(x>>i)&1;
if(siz[ch[p][!t]]-siz[ch[q][!t]]) {
p=ch[p][!t];
q=ch[q][!t];
ans|=1<<i;
}
else {
p=ch[p][t];
q=ch[q][t];
}
}
return ans;
}
signed main() {
ios::sync_with_stdio(false);
int _n;
scanf("%d%d",&_n,&m);
insert(0);
for(int i=1;i<=_n;i++) {
++n;
scanf("%d",a+i);
s[i]=s[i-1]^a[i];
insert(s[i]);
//8print();
}
sum=s[n];
for(int i=1;i<=m;i++) {
scanf("%s",op);
if(op[0]=='A') {
scanf("%d",&t1);
a[++n]=t1;
s[n]=s[n-1]^a[n];
insert(s[n]);
sum=s[n];
}
else {
scanf("%d%d%d",&t1,&t2,&t3);
printf("%d
",query(t1,t2,t3^sum));
}
}
}