字典树求异或值
Posted 可是我不配
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字典树求异或值相关的知识,希望对你有一定的参考价值。
先上模板
1 typedef long long ll; 2 3 const int maxn=1e5+10; 4 5 struct t 6 { 7 ll tree[32*maxn][3];//字典树的树部分 8 ll val[32*maxn];//字典树的终止节点 9 ll cnt;//字典树的大小 10 void init() //初始化字典树 11 { 12 cl(tree,0); 13 cl(val,0); 14 cnt=1; 15 } 16 void add(ll a) 17 { 18 int x=0,now; 19 for(int i=32; i>=0; i--) 20 { 21 now=((a>>i)&1); //当前位数 22 if(tree[x][now]==0) //没有的这个节点的话 加入这个节点 23 { 24 cl(tree[cnt],0); 25 val[cnt]=0; 26 tree[x][now]=cnt++; 27 } 28 x=tree[x][now]; 29 } 30 val[x]=a; //结尾标记 31 } 32 ll Search(ll a) //查找字典树中和a异或起来最大的值 33 { 34 int x=0,now; 35 for(int i=32; i>=0; i--) 36 { 37 now=!((a>>i)&1); 38 if(tree[x][now]) //如果和当前位相反的这个节点存在 39 { 40 x=tree[x][now]; //那么继续找这个节点下的子树 41 } 42 else 43 { 44 x=tree[x][!now]; //不存在就找自己这个节点下的子树 45 } 46 } 47 return val[x]; //结尾标记就是这个数字 48 } 49 } Trie;
接下来是例题
NBUT 1597 Find MaxXorSum
题意:
给你n个数 让你找两个数使异或值最大
思路:
构造一棵字典树
用字典树求异或值
1 #include<cstdio> 2 #include<cstring> 3 #define cl(a,b) memset(a,b,sizeof(a)) 4 #define debug(a) cerr<<#a<<"=="<<a<<endl 5 using namespace std; 6 typedef long long ll; 7 8 const int maxn=1e5+10; 9 10 ll a[maxn]; 11 12 template<typename T>inline T max(T a,T b) 13 { 14 if(a>b) return a; 15 return b; 16 } 17 18 struct t 19 { 20 ll tree[maxn*13][3],cnt; 21 void init() 22 { 23 cl(tree,0); 24 cnt=0; 25 } 26 void add(ll a) 27 { 28 int x=0,now; 29 for(int i=31; i>=0; i--) 30 { 31 now=((a>>i)&1); 32 if(tree[x][now]==0) 33 { 34 tree[x][now]=++cnt; 35 } 36 x=tree[x][now]; 37 } 38 } 39 ll Search(ll a) 40 { 41 int x=0,now; 42 ll ans=0; 43 for(int i=31; i>=0; i--) 44 { 45 ans<<=1; 46 now=!((a>>i)&1); 47 if(tree[x][now]) 48 { 49 x=tree[x][now]; 50 ans++; 51 } 52 else 53 { 54 x=tree[x][!now]; 55 } 56 } 57 return ans; 58 } 59 } Trie; 60 61 int main() 62 { 63 int T; 64 scanf("%d",&T); 65 while(T--) 66 { 67 int n; 68 scanf("%d",&n); 69 Trie.init(); 70 for(int i=0; i<n; i++) 71 { 72 scanf("%lld",&a[i]); 73 Trie.add(a[i]); 74 } 75 ll ans=0; 76 for(int i=0; i<n; i++) 77 { 78 ans=max(ans,Trie.Search(a[i])); 79 } 80 printf("%lld\n",ans); 81 } 82 return 0; 83 }/* 84 85 2 86 4 87 1 2 3 4 88 3 89 7 12 5 90 91 */
hdu 4825 Xor Sum
中文题意不解释
1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(a) cerr<<#a<<"=="<<a<<endl 4 using namespace std; 5 typedef long long ll; 6 7 const int maxn=1e5+10; 8 9 struct t 10 { 11 ll tree[32*maxn][3]; 12 ll val[32*maxn],cnt; 13 void init() 14 { 15 cl(tree,0); 16 cl(val,0); 17 cnt=1; 18 } 19 void add(ll a) 20 { 21 int x=0,now; 22 for(int i=32; i>=0; i--) 23 { 24 now=((a>>i)&1); 25 if(tree[x][now]==0) 26 { 27 cl(tree[cnt],0); 28 val[cnt]=0; 29 tree[x][now]=cnt++; 30 } 31 x=tree[x][now]; 32 } 33 val[x]=a; 34 } 35 ll Search(ll a) 36 { 37 int x=0,now; 38 for(int i=32; i>=0; i--) 39 { 40 now=!((a>>i)&1); 41 if(tree[x][now]) 42 { 43 x=tree[x][now]; 44 } 45 else 46 { 47 x=tree[x][!now]; 48 } 49 } 50 return val[x]; 51 } 52 } Trie; 53 54 int main() 55 { 56 int T,cas=1; 57 scanf("%d",&T); 58 while(T--) 59 { 60 int n,m,x; 61 scanf("%d%d",&n,&m); 62 Trie.init(); 63 for(int i=0; i<n; i++) 64 { 65 scanf("%d",&x); 66 Trie.add(x); 67 } 68 printf("Case #%d:\n",cas++); 69 for(int i=0; i<m; i++) 70 { 71 scanf("%d",&x); 72 printf("%lld\n",Trie.Search(x)); 73 } 74 } 75 return 0; 76 }/* 77 78 2 79 3 2 80 3 4 5 81 1 82 5 83 4 1 84 4 6 5 6 85 3 86 87 */
以上是关于字典树求异或值的主要内容,如果未能解决你的问题,请参考以下文章
Chip Factory---hdu5536(异或值最大,01字典树)