码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4103[Thu Summer Camp 2015]异或运算(可持久化trie树)

时间:2018-11-28 00:25:04      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:nbsp   scanf   main   枚举   异或运算   数据   可持久化trie树   线段   algo   

一看数据范围,n很小m很大,对长的那一维建可持久化线段树,另一维暴力枚举

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,m,cnt,tot,p;
 7 int rt[300005];
 8 int x[2005];
 9 int y[300005];
10 struct Trie{
11     int son[2];
12     int siz;
13 }tr[10000005];
14 void insert(int fr,int tim,int s){
15     int now=rt[tim]=++tot;
16     for(int i=30;i>=0;i--){
17         tr[now].son[!((s>>i)&1)]=tr[fr].son[!((s>>i)&1)];
18         tr[now].son[(s>>i)&1]=++tot;
19         now=tr[now].son[(s>>i)&1];
20         fr=tr[fr].son[(s>>i)&1];
21         tr[now].siz=tr[fr].siz+1;
22     }
23 } 
24 int query(int u,int d,int l,int r,int k){
25     int now[2005];int fr[2005];
26     int ret=0;
27     for(int i=u;i<=d;i++){
28         now[i]=rt[r];
29         fr[i]=rt[l-1];
30     }
31     for(int i=30;i>=0;i--){
32         int sum=0;
33         for(int j=u;j<=d;j++){
34             int s=x[j];
35             sum+=tr[tr[now[j]].son[!((s>>i)&1)]].siz-tr[tr[fr[j]].son[!((s>>i)&1)]].siz;
36         }
37         if(sum>=k){
38             ret|=(1<<i);
39             for(int j=u;j<=d;j++){
40                 int s=x[j];
41                 now[j]=tr[now[j]].son[!((s>>i)&1)];
42                 fr[j]=tr[fr[j]].son[!((s>>i)&1)];
43             }
44         }else{
45             k-=sum;
46             for(int j=u;j<=d;j++){
47                 int s=x[j];
48                 now[j]=tr[now[j]].son[(s>>i)&1];
49                 fr[j]=tr[fr[j]].son[(s>>i)&1];
50             }
51         }
52     }
53     return ret;
54 }
55 int main(){
56     scanf("%d%d",&n,&m);
57     for(int i=1;i<=n;i++){
58         scanf("%d",&x[i]);
59     }
60     insert(0,0,0);
61     for(int i=1;i<=m;i++){
62         scanf("%d",&y[i]);
63         insert(rt[i-1],i,y[i]);
64     }
65     scanf("%d",&p);
66     for(int i=1;i<=p;i++){
67         int u,d,l,r,k;
68         scanf("%d%d%d%d%d",&u,&d,&l,&r,&k);                         
69         int ans=query(u,d,l,r,k);
70         printf("%d\n",ans);
71     }
72     return 0;
73 }

 

bzoj4103[Thu Summer Camp 2015]异或运算(可持久化trie树)

标签:nbsp   scanf   main   枚举   异或运算   数据   可持久化trie树   线段   algo   

原文地址:https://www.cnblogs.com/lnxcj/p/10029811.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!