标签:col ++ 思路 find 就是 color 情况 进制 取反
今天本来想写一个可持久化Trie树,发现这道题一直没做就补上了。
其实思路很简单,假如说两个数,和同一个数异或,很显然,由于进制,高位上的一个1可以大于低位上所有1,所以即使后面的情况再糟糕,也比取后面好的值高(其实就是1000比0111大)
所以可以建一个01线段树,从高往低插入一个数,比较时取反即可^_^
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int n,m,t; 6 struct pnt{ 7 int child[2]; 8 int end; 9 void res() 10 { 11 memset(child,0,sizeof(child)); 12 end=0; 13 } 14 }; 15 struct Trie{ 16 pnt tr[3300000]; 17 int siz; 18 void dst() 19 { 20 siz=0; 21 tr[0].res(); 22 } 23 void insert(int x,int l) 24 { 25 int root=0; 26 for(int i=31;i>=0;i--) 27 { 28 int tmp=(bool)((x&(1<<i))!=0); 29 if(!tr[root].child[tmp]) 30 { 31 tr[root].child[tmp]=++siz; 32 tr[siz].res(); 33 } 34 root=tr[root].child[tmp]; 35 } 36 tr[root].end=l; 37 } 38 int find(int x) 39 { 40 int root=0; 41 for(int i=31;i>=0;i--) 42 { 43 int tmp=(bool)((x&(1<<i))!=0); 44 tmp=tmp^1; 45 if(tr[root].child[tmp]) 46 root=tr[root].child[tmp]; 47 else 48 root=tr[root].child[1^tmp]; 49 } 50 return tr[root].end; 51 } 52 }trie; 53 int a[1000000]; 54 int main() 55 { 56 scanf("%d",&t); 57 for(int ccc=1;ccc<=t;ccc++) 58 { 59 printf("Case #%d:\n",ccc); 60 scanf("%d%d",&n,&m); 61 trie.dst(); 62 for(int i=1;i<=n;i++) 63 { 64 scanf("%d",&a[i]); 65 trie.insert(a[i],i); 66 } 67 for(int i=1;i<=m;i++) 68 { 69 int ask; 70 scanf("%d",&ask); 71 printf("%d\n",a[trie.find(ask)]); 72 } 73 } 74 return 0; 75 }
标签:col ++ 思路 find 就是 color 情况 进制 取反
原文地址:https://www.cnblogs.com/blog-Dr-J/p/9452378.html