bzoj4546-codechef XRQRS(可持久化Trie)

中文题题意我就不说了

解析: 可持久化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

 

posted @ 2016-08-08 21:10  wust_ouyangli  阅读(164)  评论(0编辑  收藏  举报