题目: https://www.lydsy.com/JudgeOnline/problem.php?id=3261
题意:
给定n个数,q个操作;
操作有两种类型;
第一种:在n个数后添加一个数;
第二种:给定L、R、X,求a[p] xor a[p+1] xor … xor a[N] xor x,其中p∈[L,R]
分析:
可持久化Trie裸题
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long llong;
const int tmax=600005;
struct Trie{
int cnt;
int ch[tmax*26][2],sum[tmax*26];
inline void init()
{
cnt=0;
memset(ch,0,sizeof(ch));
memset(sum,0,sizeof(sum));
return;
}
inline int insert(int pre,int x)
{
int o,u,id;
o=u=++cnt;
for(int i=25;i>=0;i--)
{
//复制儿子的所有相关信息
ch[u][0]=ch[pre][0];
ch[u][1]=ch[pre][1];
sum[u]=sum[pre]+1;
id=(x&(1<<i))>0;
pre=ch[pre][id];//在原树上下移一层
ch[u][id]=++cnt;//在新树上新建儿子节点
u=ch[u][id];//在新树上下移一层
}
sum[u]=sum[pre]+1;
return o;
}
inline int query(int l,int r,int x) //返回a[l,r]内xor x最大是多少(注意不是返回a而是返回答案)
{
int ans=0,id;
for(int i=25;i>=0;i--)
{
id=(x&(1<<i))>0;
if(sum[ch[r][id^1]]-sum[ch[l][id^1]]>0)
{
ans+=(1<<i);
r=ch[r][id^1];
l=ch[l][id^1];
}
else
{
r=ch[r][id];
l=ch[l][id];
}
}
return ans;
}
}trie;
int root[tmax];
int main()
{
int tmp,leftSum=0,l,r,n,m;
char kind[5];
scanf("%d%d",&n,&m);
trie.init();
n++;
for(int i=1;i<=n;i++)
{
if(i==1) tmp=0;
else scanf("%d",&tmp);
leftSum^=tmp;
root[i]=trie.insert(root[i-1],leftSum);
}
for(int i=1;i<=m;i++)
{
scanf("%s",kind);
if(kind[0]=='A')
{
scanf("%d",&tmp);
leftSum^=tmp;
root[n+1]=trie.insert(root[n],leftSum);
n++;
}
else
{
scanf("%d%d%d",&l,&r,&tmp);
printf("%d\n",trie.query(root[l-1],root[r],tmp^leftSum));
}
}
return 0;
}