您的位置:首页 > 其它

bzoj4546-codechef XRQRS(可持久化Trie)

2016-08-08 21:10 423 查看
中文题题意我就不说了

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

代码

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


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: