bzoj4546 codechef XRQRS

  可持久化trie

  代码

  1 #include<cstdio>
  2 #define N 10000010
  3 #define M 600100
  4 int tt,m,n;
  5 int i,tot,typ,a,b,c,last,num;
  6 int trie[M],v[30];
  7 int cnt,f[N][3];
  8 void add(int &x,int y,int z)
  9 {
 10     x=++cnt;
 11     int tmp=x,i;
 12     for (i=1;i<=19;i++)v[i]=z%2,z/=2;
 13     for (i=19;i>=1;i--)
 14     {
 15         f[tmp][0]=f[y][0];
 16         f[tmp][1]=f[y][1];
 17         f[tmp][2]=f[y][2]+1;
 18         f[tmp][v[i]]=++cnt;
 19         tmp=f[tmp][v[i]];y=f[y][v[i]];
 20     }
 21     f[tmp][2]=f[y][2]+1;
 22 }
 23 int query1(int x,int y,int z)
 24 {
 25     int ans=0,i;
 26     for (i=1;i<=19;i++)v[i]=z%2,z/=2;
 27     for (i=19;i>=1;i--)
 28     {
 29         if (v[i])
 30         {
 31             ans+=(f[f[y][0]][2]-f[f[x][0]][2]);
 32             x=f[x][1];
 33             y=f[y][1];
 34         }
 35         else
 36         {
 37             x=f[x][0];
 38             y=f[y][0];
 39         }
 40     }
 41     ans+=(f[y][2]-f[x][2]);
 42     return ans;
 43 }
 44 int query2(int x,int y,int z)
 45 {
 46     int i,ans=0;
 47     for (i=19;i>=1;i--)
 48     {
 49         if (f[f[y][0]][2]-f[f[x][0]][2]>=z)
 50         {
 51             //printf("0 %d\n",f[y][2]);
 52             x=f[x][0];
 53             y=f[y][0];
 54         }
 55         else
 56         {
 57         //    printf("1 %d\n",f[y][2]);
 58             ans+=(1<<(i-1));
 59             z=z-(f[f[y][0]][2]-f[f[x][0]][2]);
 60             x=f[x][1];
 61             y=f[y][1];
 62         }
 63     }
 64     return ans;
 65 }
 66 int query3(int x,int y,int z)
 67 {
 68     int i,ans=0;
 69     for (i=1;i<=19;i++)
 70     v[i]=z%2,z/=2;
 71     for (i=19;i>=1;i--)
 72     {
 73         if (f[f[y][1-v[i]]][2]-f[f[x][1-v[i]]][2])
 74         {
 75             ans+=(1-v[i])*(1<<(i-1));
 76             y=f[y][1-v[i]];
 77             x=f[x][1-v[i]];
 78         }
 79         else
 80         {
 81             ans+=v[i]*(1<<(i-1));
 82             y=f[y][v[i]];
 83             x=f[x][v[i]];
 84         }
 85     }
 86     return ans;
 87 }
 88 int main()
 89 {
 90     scanf("%d",&n);
 91     tot=0;trie[0]=++cnt;
 92     for (i=1;i<=n;i++)
 93     {
 94         scanf("%d",&typ);
 95         if (typ==1)
 96         {
 97             scanf("%d",&a);
 98             tot++;add(trie[tot],trie[tot-1],a);
 99         }
100         else
101         if (typ==2)
102         {
103             scanf("%d%d%d",&a,&b,&c);
104             printf("%d\n",query3(trie[a-1],trie[b],c));
105         }
106         else
107         if (typ==3)
108         {
109             scanf("%d",&a);
110             tot-=a;cnt=trie[tot+1]-1;
111         }
112         else
113         if (typ==4)
114         {
115             scanf("%d%d%d",&a,&b,&c);
116             printf("%d\n",query1(trie[a-1],trie[b],c));
117         }
118         else
119         if (typ==5)
120         {
121             scanf("%d%d%d",&a,&b,&c);
122             printf("%d\n",query2(trie[a-1],trie[b],c));
123         }
124     }
125 }

 

转载于:https://www.cnblogs.com/fzmh/p/5424743.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值