Codechef Xor Queries(可持久化字典树)

来源:互联网 发布:淘宝 企业店铺 假货 编辑:程序博客网 时间:2024/04/30 02:46

题意:
给定一个初始时为空的整数序列(元素由1开始标号)以及一些询问:
类型0:在数组最后加入数字x
类型1:在区间[L,R]中找到数字y,最大化(x^y)
类型2:删除数组最后k个元素
类型3:在区间[L,R]中,统计小于等于x的元素个数
类型4:在区间[L,R]中,找到第k小的数
(M<=5e5,x<=5e5)


#include<cstdio>#include<algorithm>using namespace std;const int N=5e5+100;struct Trie{    int ch[2],sum,dep;}T[N*30];int root[N],sz;void insert(int &i,int d,int x,int v){    T[++sz]=T[i],i=sz;    T[i].dep=d+1;    T[i].sum+=v;    //此时判断的是上一位的d    if(d<0) return ;    int p=(x>>d)&1;    insert(T[i].ch[p],d-1,x,v);}void Query_max_xor(int L,int R,int d,int x,int &ans){    if(d<0)     return ;    int p=(x>>d)&1;    if(T[ T[R].ch[p^1] ].sum-T[ T[L].ch[p^1] ].sum)        ans+=(p^1)*(1<<d),Query_max_xor(T[L].ch[p^1],T[R].ch[p^1],d-1,x,ans);    else    ans+=p*(1<<d),Query_max_xor(T[L].ch[p],T[R].ch[p],d-1,x,ans);}void Query_equal_to_x(int L,int R,int d,int x,int &ans){    if(d<0)     {ans+=T[R].sum-T[L].sum;return ;}    int p=(x>>d)&1;    if(p==1)  ans+=T[ T[R].ch[0] ].sum-T[ T[L].ch[0] ].sum;    Query_equal_to_x(T[L].ch[p],T[R].ch[p],d-1,x-p*(1<<d),ans);}void Query_kth(int L,int R,int d,int x,int &ans){    if(d<0)     return ;    int k=T[ T[R].ch[0] ].sum-T[ T[L].ch[0] ].sum;    if(k>=x)    Query_kth(T[L].ch[0],T[R].ch[0],d-1,x,ans);    else   ans+=(1<<d),Query_kth(T[L].ch[1],T[R].ch[1],d-1,x-k,ans);}int main(){    int m,n=0,L,R,ans,op,x;    while(scanf("%d",&m)!=EOF){        sz=0,root[0]=0;        while(m--){            scanf("%d",&op);            if(op==0){                scanf("%d",&x);                root[++n]=root[n-1];                insert(root[n],23,x,1);            }            else if(op==1){                scanf("%d%d%d",&L,&R,&x);                Query_max_xor(root[L-1],root[R],23,x,ans=0);                printf("%d\n",ans);            }            else if(op==2)                scanf("%d",&x),n-=x;            else if(op==3){                scanf("%d%d%d",&L,&R,&x);                Query_equal_to_x(root[L-1],root[R],23,x,ans=0);                printf("%d\n",ans);            }            else if(op==4){                scanf("%d%d%d",&L,&R,&x);                Query_kth(root[L-1],root[R],23,x,ans=0);                printf("%d\n",ans);            }        }    }    return 0;}
0 0