题目描述
题解
设
sum[i]
表示
1...i
的异或和,那么题目要求的即为
sum[i]
^
sum[n]
^
x
。由于
将
sum[i]
转化为二进制数,然后建立可持久化trie树。利用前缀和相减的思想,对于每一个询问只需要根据
sum[n]
^
x
的每一个二进制位在trie树上对应寻找就可以了,尽量让异或值为1,实在不行就为0。
需要注意的一点是,答案可能为
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 600005
#define sz 25
int n,m,x,tot,cnt,size,l,r,ans;
int root[N];
int sum[N*30],ch[N*30][2];
int dig[30];
int read()
{
int x=0; char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
void write(int x)
{
if (!x) {puts("0");return;}
dig[0]=0;
while (x)
{
dig[++dig[0]]=x%10;
x/=10;
}
for (int i=dig[0];i>=1;--i) putchar('0'+dig[i]);
putchar('\n');
}
void insert(int &now,int x,int dep)
{
sum[++size]=sum[now]+1,ch[size][0]=ch[now][0],ch[size][1]=ch[now][1];now=size;
if (dep==-1) return;
int k=(x>>dep)&1;
if (!k) insert(ch[now][0],x,dep-1);
else insert(ch[now][1],x,dep-1);
}
void query(int l,int r,int x,int dep)
{
if (dep==-1) return;
int k=(x>>dep)&1;
if (sum[ch[r][k^1]]-sum[ch[l][k^1]]>0)
{
ans|=1<<dep;
query(ch[l][k^1],ch[r][k^1],x,dep-1);
}
else
query(ch[l][k],ch[r][k],x,dep-1);
}
int main()
{
n=read();m=read();
for (int i=1;i<=n;++i)
{
x=read();
tot^=x;root[i]=root[i-1];
insert(root[i],tot,sz-1);
}
cnt=n;
for (int i=1;i<=m;++i)
{
char opt=getchar();
while (opt!='A'&&opt!='Q') opt=getchar();
if (opt=='A')
{
x=read();
tot^=x;++cnt;root[cnt]=root[cnt-1];
insert(root[cnt],tot,sz-1);
}
else
{
l=read();r=read();x=read();ans=0;
--l,--r;l=max(l,0);r=max(r,0);
query(root[l-1],root[r],tot^x,sz-1);
if (l==0) ans=max(ans,tot^x);
write(ans);
}
}
}
总结
①牵扯到xor的东西要有意识地想到用trie树。