刚学
trie的可持久化可以快速建一棵和已知trie相似的trie
从而做到保存历史版本,在线构造两棵trie的差并查询
运用位运算与trie的联系就可以搞完这题了
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define mmst(a, b) memset(a, b, sizeof(a))
#define mmcp(a, b) memcpy(a, b, sizeof(b))
typedef long long LL;
const int N=600600;
int n,m;
int a[N];
int er[50];
int ro[N],son[N*24][2],sum[N*24],cnt;
char cc[5];
int Insert(int x,int val)
{
int res,y;
res=y=++cnt;
for(int i=23;i>=0;i--)
{
son[y][0]=son[x][0];
son[y][1]=son[x][1];
sum[y]=sum[x]+1;
int t=(val&er[i])>>i;
x=son[x][t];
son[y][t]=++cnt;
y=son[y][t];
}
sum[y]=sum[x]+1;
return res;
}
int query(int l,int r,int val)
{
int res=0;
for(int i=23;i>=0;i--)
{
int t=(val&er[i])>>i;
if(sum[son[r][t^1]]-sum[son[l][t^1]])
{
res+=er[i];
r=son[r][t^1];
l=son[l][t^1];
}
else
{
r=son[r][t];
l=son[l][t];
}
}
return res;
}
int main()
{
er[0]=1;
for(int i=1;i<=30;i++)
er[i]=er[i-1]*2;
cin>>n>>m;
n++;
ro[1]=Insert(0,0);
for(int i=2;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]^=a[i-1];
ro[i]=Insert(ro[i-1],a[i]);
}
while(m--)
{
int l,r,x;
scanf("%s",cc);
if(cc[0]=='A')
{
n++;
scanf("%d",&a[n]);
a[n]^=a[n-1];
ro[n]=Insert(ro[n-1],a[n]);
}
else
{
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",query(ro[l-1],ro[r],a[n]^x));
}
}
return 0;
}