中文题题意我就不说了

解析: 可持久化Trie的模板题,详见注释

代码

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxbit=;
const int maxn=;
int tr[];
struct PerTrie
{
int id;
int next[maxn][],num[maxn];
void init(){ id=next[][]=next[][]=num[]=; }//初始化
int f(int x,int i){ return (x>>i)&; } //判断x的第i位为0或1
void Insert(int& rt,int pre,int x,int pos) //插入
{
rt=++id;
next[rt][]=next[pre][]; //赋等
next[rt][]=next[pre][];
num[rt]=num[pre]+; //数量加1
if(pos==-) return;
int d=f(x,pos);
Insert(next[rt][d],next[pre][d],x,pos-);
}
int MaxXor(int l,int r,int x)
{
int ret=;
for(int i=maxbit;i>=;i--)
{
int d=f(x,i);
int a=next[l][d^],b=next[r][d^];
if(num[b]-num[a]>) ret|=(<<i),l=a,r=b; //判断是否存在
else l=next[l][d],r=next[r][d];
}
return ret;
}
int MinNum(int l,int r,int x)
{
int ret=;
for(int i=maxbit;i>=;i--)
{
int d=f(x,i);
if(d) ret+=num[next[r][]]-num[next[l][]]; //比它小的加上
l=next[l][d]; r=next[r][d];
}
ret+=num[r]-num[l]; //<=要加上它,<的话就不用了
return ret;
}
int Kth(int l,int r,int k)
{
int ret=;
for(int i=maxbit;i>=;i--)
{
int t=num[next[r][]]-num[next[l][]];
if(t>=k) l=next[l][],r=next[r][]; //足够
else ret|=(<<i),l=next[l][],r=next[r][],k-=t;
}
return ret;
}
}PT;
int main()
{
int Q;
scanf("%d",&Q);
int type,l,r,x,cnt=;
tr[]=;
PT.init();
while(Q--)
{
scanf("%d",&type);
if(type==)
{
scanf("%d",&x);
++cnt;
PT.Insert(tr[cnt],tr[cnt-],x,maxbit); //插入新的值
}
else if(type==)
{
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",PT.MaxXor(tr[l-],tr[r],x)^x);
}
else if(type==)
{
scanf("%d",&x);
cnt-=x;
}
else if(type==)
{
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",PT.MinNum(tr[l-],tr[r],x));
}
else
{
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",PT.Kth(tr[l-],tr[r],x));
}
}
return ;
}
05-06 13:11