01字典树的是只含有0和1两种字符的字典树,在使用它的时候,把若干数字转成二进制后插入其中
在查询树中的哪个数字和给定数字有最大异或值的时候,从根开始贪心查询就ok了
HDU4825是一道裸题:给出n个数和m次询问,每次询问给出一个数x,问在n个数中哪个数与x异或值最大
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=1000005; 4 int n,m,rt; 5 int a[maxn],v[3500005],s[3500005][2]; 6 void in(int x,int id) 7 { 8 //把每一个数字拆成二进制从高到低插入Trie树里面 9 int op,u=0; 10 for(int i=31;i>=0;i--) 11 { 12 op=((x&(1<<i))!=0); 13 if(s[u][op]==0) s[u][op]=rt++; 14 u=s[u][op]; 15 } 16 v[u]=id; 17 } 18 int get(int x) 19 { 20 int op,u=0; 21 for(int i=31;i>=0;i--) 22 { 23 op=((x&(1<<i))!=0); 24 if(s[u][op^1]!=0) //尽可能走与当前位不同的点 25 u=s[u][op^1]; 26 else u=s[u][op]; 27 } 28 return a[v[u]]; 29 } 30 int main() 31 { 32 int T,u; 33 scanf("%d",&T); 34 for(int cas=1;cas<=T;cas++) 35 { 36 scanf("%d%d",&n,&m); 37 rt=1; 38 memset(s,0,sizeof(s)); 39 memset(v,0,sizeof(v)); 40 for(int i=1;i<=n;i++) 41 { 42 scanf("%d",&a[i]); 43 in(a[i],i); 44 } 45 printf("Case #%d:\n",cas); 46 for(int i=1;i<=m;i++) 47 { 48 scanf("%d",&u); 49 printf("%d\n",get(u)); 50 } 51 } 52 return 0; 53 }
原文地址:https://www.cnblogs.com/aininot260/p/9519839.html
时间: 2024-11-05 18:27:08