标签:插入 cout 程序设计 blank tps AC type family 空间
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 }
标签:插入 cout 程序设计 blank tps AC type family 空间
原文地址:https://www.cnblogs.com/lnu161403214/p/9246363.html