首届湖北省大学程序设计竞赛I题(可持久化trie)

https://www.nowcoder.com/acm/contest/104/H

题目大意:给你n个数,m个询问,每个询问为给出L,R,X。

     问[L,R]中的哪个数与X异或值最大,输出这个最大值。

 

可持久化trie的模板题,下面简说一下:

1,根据异或的特征,将数都转换成二进制,自然越是高位与X不同,所得的值越大,所以将数按从高位到低位插入到01trie中,再从01trie中尽量找一个与X二进制串不匹配的就行了。

2,本题是区间询问,不可能每次询问都建一颗01trie,所以采用可持久化结构能够访问历史信息的特点。即对每个前缀建一颗01trie,每个节点记录该节点的数量,就能根据可减性得到任何一个区间的01trie。

3,每个前缀01trie的建立都能在上一个前缀的基础上建立,只需新建插入一个数后改变的那条路径。这样的话建立一个可持久化Trie时间,空间均在O(nlogn)

AC代码:

 1 #include<bits/stdc++.h>
 2 #define N 200005
 3 using namespace std;
 4 typedef long long ll;
 5 typedef struct NODE{
 6     int sum;  //该节点数量 
 7     int son[2];
 8     NODE(){son[0]=son[1]=0;sum=0;}
 9 }node;
10 struct Trie{
11     node b[N*35]; //b为待开节点 
12     int a[N];  //a为根节点点数组 
13     int tot;
14     Trie() {tot=1;}    
15     int ins(int x,ll num) //在x中插入num 
16     {
17         int tmp,y;
18         tmp=y=tot++;
19         for(ll i=34;i>=0;i--)
20         {
21             b[y].son[0]=b[x].son[0];
22             b[y].son[1]=b[x].son[1];
23             if(num&(1LL<<i))
24             {
25                 b[y].son[1]=tot++;
26                 y=b[y].son[1];
27                 x=b[x].son[1];
28             }
29             else b[y].son[0]=tot++,y=b[y].son[0],x=b[x].son[0];
30             b[y].sum=b[x].sum+1;
31                 
32         
33         }
34          return tmp;
35     } 
36     ll query(int l,int r,ll val)
37     {    ll tmp=0;
38         
39         for(ll i=34;i>=0;i--)
40         {    int x,y;
41             int t=(val&(1LL<<i))==0;
42             
43             x=b[l].son[t],y=b[r].son[t];
44         
45         
46             if(b[y].sum-b[x].sum)
47             {
48                 tmp+=1LL<<i;
49                 
50             }
51             else x=b[l].son[t^1],y=b[r].son[t^1];
52             l=x,r=y;
53         }
54     
55         return tmp;
56     } 
57 }T;
58 
59 int main()
60 {
61     int n;
62     cin>>n;
63     T.a[0]=0;
64     for(int i=1;i<=n;i++)
65     {
66         int x;
67         cin>>x;
68         T.a[i]=T.ins(T.a[i-1],x);
69     }
70     int m;
71     cin>>m;
72     while(m--)
73     {
74         ll x,l,r;
75         cin>>x>>l>>r;
76         ll y=T.query(T.a[l-1],T.a[r],x);
77         cout<<y<<endl;
78     }
79     
80     return 0;
81 }

  

猜你喜欢

转载自www.cnblogs.com/lnu161403214/p/9246363.html
今日推荐