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

题目链接:codechef Xor Queries

题意:

题解:

一棵可持久化字典树就行了。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 using namespace std;
 4 
 5 const int N=5e5+7;
 6 struct Node{int son[2],cnt;}ch[N*40];
 7 int root[N],cnt,ed,n;
 8 
 9 void ins(int &x,int y,int v,int i=20)
10 {
11     ch[x=++cnt]=ch[y],ch[x].cnt++;
12     if(i<0)return;
13     int now=(v>>i)&1;
14     ins(ch[x].son[now],ch[y].son[now],v,i-1);
15 }
16 
17 int ask_xor(int x,int y,int v,int i=20,int ans=0)
18 {
19     if(i<0)return ans;
20     int now=(v>>i)&1;
21     if(ch[ch[y].son[now^1]].cnt-ch[ch[x].son[now^1]].cnt>0)
22         return ask_xor(ch[x].son[now^1],ch[y].son[now^1],v,i-1,ans+(1<<i));
23     else return ask_xor(ch[x].son[now],ch[y].son[now],v,i-1,ans);
24 }
25 
26 int ask_num(int x,int y,int v,int i=20,int ans=0)
27 {
28     if(i<0)return ans+ch[y].cnt-ch[x].cnt;
29     int now=(v>>i)&1,tmp=0;
30     if(now)tmp+=ch[ch[y].son[0]].cnt-ch[ch[x].son[0]].cnt;
31     return ask_num(ch[x].son[now],ch[y].son[now],v,i-1,ans+tmp);
32 }
33 
34 int kth(int x,int y,int v,int i=20,int ans=0)
35 {    
36     if(i<0)return ans;
37     int tmp=ch[ch[y].son[0]].cnt-ch[ch[x].son[0]].cnt;
38     if(tmp>=v)return kth(ch[x].son[0],ch[y].son[0],v,i-1,ans);
39     else return kth(ch[x].son[1],ch[y].son[1],v-tmp,i-1,ans+(1<<i));
40 }
41 
42 int main(){
43     scanf("%d",&n);
44     while(n--)
45     {
46         int l,r,x;
47         scanf("%d",&x);
48         if(x==0)
49         {
50             scanf("%d",&x),ed++;
51             ins(root[ed],root[ed-1],x);
52         }
53         else if(x==1)
54         {
55             scanf("%d%d%d",&l,&r,&x);
56             printf("%d
",ask_xor(root[l-1],root[r],x));
57         }
58         else if(x==2)
59         {
60             scanf("%d",&x);
61             ed-=x,cnt=root[ed+1];
62         }
63         else if(x==3)
64         {
65             scanf("%d%d%d",&l,&r,&x);
66             printf("%d
",ask_num(root[l-1],root[r],x));
67         }
68         else 
69         {
70             scanf("%d%d%d",&l,&r,&x);
71             printf("%d
",kth(root[l-1],root[r],x));
72         }
73     }
74     return 0;
75 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/7147114.html