# [BZOJ4103][Thu Summer Camp 2015]异或运算 可持久化Trie树

## 4103: [Thu Summer Camp 2015]异或运算

Time Limit: 20 Sec  Memory Limit: 512 MB

3 3
1 2 4
7 6 5
3
1 2 1 2 2
1 2 1 3 4
2 3 2 3 4

6
5
1

## HINT

对于100%的数据，0<=Xi,Yj<2^31,

1<=u<=d<=n<=1000,
1<=l<=r<=m<=300000,
1<=k<=(d-u+1)*(r-l+1),
1<=p<=500.

 1 #include <cstdio>
2 #include <cstring>
3 #include <vector>
4 using namespace std;
5 typedef long long LL;
6 const int M=300100,N=1010;
7 int a,b,c,d,k,n,m,x[N];LL bin[40];
8 struct Trie
9 {
10     int size;Trie *ch[2];
11     Trie(){size=0;ch[0]=ch[1]=NULL;}
12 }*null=new Trie(),*root[M];
13 vector<Trie*>v[5];
14 vector<int>vec;
15 inline Trie* newTrie(){Trie *o=new Trie();o->ch[0]=o->ch[1]=null;return o;}
16 void insert(Trie *&o,Trie *old,int val,int i)
17 {
18     if(i<0)return;
19     int d=((val&bin[i])==bin[i]);
20     o->ch[d]=newTrie();o->ch[d^1]=old->ch[d^1];
21     o->ch[d]->size=old->ch[d]->size+1;
22     insert(o->ch[d],old->ch[d],val,i-1);
23 }
24 inline int query()
25 {
26     v[1].clear(),v[2].clear();vec.clear();
27     for(int i=a;i<=b;i++)
28         vec.push_back(x[i]),v[1].push_back(root[c-1]),v[2].push_back(root[d]);
29     int ret=0;
30     for(int i=30;~i;i--)
31     {
32         int tmp=0;
33         for(int j=0,len=v[1].size();j<len;j++)
34         {
35             int d=((vec[j]&bin[i])==bin[i]);
36             tmp+=v[2][j]->ch[d^1]->size-v[1][j]->ch[d^1]->size;
37         }
38         if(tmp>=k)
39         {
40             ret|=bin[i];
41             for(int j=0,len=v[1].size();j<len;j++)
42             {
43                 int d=((vec[j]&bin[i])==bin[i]);
44                 v[1][j]=v[1][j]->ch[d^1],v[2][j]=v[2][j]->ch[d^1];
45             }
46         }
47         else
48         {
49             k-=tmp;
50             for(int j=0,len=v[1].size();j<len;j++)
51             {
52                 int d=((vec[j]&bin[i])==bin[i]);
53                 v[1][j]=v[1][j]->ch[d],v[2][j]=v[2][j]->ch[d];
54             }
55         }
56     }
57     return ret;
58 }
59 int main()
60 {
61     int q;scanf("%d%d",&n,&m);
62     bin[0]=1;for(int i=1;i<=35;i++)bin[i]=bin[i-1]<<1;
63     root[0]=newTrie();null->ch[0]=null->ch[1]=null;
64     for(int i=1;i<=n;i++)scanf("%d",&x[i]);
65     for(int i=1;i<=m;i++)
66         root[i]=newTrie(),scanf("%d",&a),insert(root[i],root[i-1],a,30);
67     scanf("%d",&q);
68     while(q--)
69         scanf("%d%d%d%d%d",&a,&b,&c,&d,&k),printf("%d\n",query());
70 }

Progress is not created by contented people.
posted @ 2017-08-03 21:23  LadyLex  阅读(264)  评论(0编辑  收藏  举报