ACM: Find MaxXorSum 解题报告-字典树
Find MaxXorSum Time Limit:2000MS Memory Limit:65535KB 64bit IO Format: Description Given n non-negative integers, you need to find two integers a and b that a xor b is maximum. xor is exclusive-or. Input Input starts with an integer T(T <= 10) denoting the number of tests. For each test case, the first line contains an integer n(n <= 100000), the next line contains a1, a2, a3, ......, an(0 <= ai <= 1000000000); Output For each test case, print you answer.
Sample Input 2 4 1 2 3 4 3 7 12 5
Sample Output 7 11
这个题目其实思路很简单,就我知道的写法有Trie树指针和静态数组两种写法,一开始写的指针用了pow函数TLE了2次,然后换位运算又TLE两次醉了。。
后面换成静态数组数组开大了RE了一次。。。哭。。。
这是AC代码:
1 #include"iostream" 2 #include"algorithm" 3 #include"cstdio" 4 #include"cmath" 5 #include"cstring" 6 #define MX 1400000 7 #define INF 0x3f3f3f3f 8 #define lson l,m,rt<<1 9 #define rson m+1,r,rt<<1|1 10 using namespace std; 11 int tree[MX][2],xx; 12 13 void BuildTrie(long long a) { 14 int i=31; 15 int p=0; 16 while(0<=i) { 17 bool num=a&(1<<i); 18 if(!tree[p][num]) { //如果节点为空 19 tree[p][num]=++xx;//标记并创建新的子节点 20 } 21 p=tree[p][num]; 22 // cout<<"YES"<<i<<" B is:"<<num<<"\n"; //建立的Trie树的样子 23 i--; 24 } 25 } 26 27 long long Query(long long a) { 28 int i=31,p=0; 29 long long ans=0; 30 while(0<=i) { 31 bool num=!(a&(1<<i)); //取反查找 32 if(tree[p][num]) p=tree[p][num],ans+=1<<i;//如果和原来的那一为相反的存在的话,返回值就加上,并且在这个支路走 33 else p = tree[p][!num]; //按照相同的顺序找 34 // cout<<"YES"<<i<<" B is:"<<num<<" ans is:"<<ans<<endl; //查询时候的Trie树的样子 35 i--; 36 } 37 return ans; 38 } 39 40 int main() { 41 int T,n; 42 long long a[100050],ans; 43 scanf("%d",&T); 44 while(T--) { 45 ans=0; 46 memset(tree,0,sizeof(tree)); 47 xx=0; 48 scanf("%d",&n); 49 for(int i=1; i<=n; i++) { 50 scanf("%I64d",&a[i]); 51 BuildTrie(a[i]); 52 } 53 //cout<<"YES1\n"; 54 for(int i=1; i<=n; i++) { 55 ans=max(ans,Query(a[i])); 56 } 57 // cout<<"YES2\n"; 58 printf("%I64d\n",ans); 59 } 60 return 0; 61 }
这是指针的写法,感觉复杂度和上面的没啥区别,为啥就TLE了呢? 希望有人知道给我指点下。
1 #include"iostream" 2 #include"algorithm" 3 #include"cstdio" 4 #include"cmath" 5 #include"cstring" 6 #define MX 110000 7 #define INF 0x3f3f3f3f 8 #define lson l,m,rt<<1 9 #define rson m+1,r,rt<<1|1 10 using namespace std; 11 12 struct Trie { 13 Trie *next[2]; 14 } root; 15 16 void BuildTrie(int a) { 17 Trie *p=&root,*q; 18 int i=31; 19 while(i>=0) { 20 bool num=a&(1<<i); 21 if(p->next[num]==NULL) { 22 q=(Trie *)malloc(sizeof(root));//申请一块新内存; //动态分配内存 23 q->next[1]=NULL; 24 q->next[0]=NULL; //清空申请内存的所有子节点 25 p->next[num]=q; //往子节点下去继续记录字典树 26 p=p->next[num]; 27 } else { 28 p=p->next[num]; 29 } 30 // cout<<"YES"<<i<<" B is:"<<num<<"\n"; //建立的Trie树的样子 31 i--; 32 } 33 } 34 35 long long Query(int a) { 36 Trie *p=&root; 37 long long ans=0; 38 int i=31; 39 while(0<=i) { 40 bool num=a&(1<<i); 41 if(p->next[!num]!=NULL) p=p->next[!num],ans+=1<<(i);//如果和原来的那一为相反的存在的话,返回值就加上,并且在这个支路走 42 else if(p->next[num]!=NULL) p=p->next[num]; //按照相同的顺序找 43 // cout<<"YES"<<i<<" B is:"<<num<<"\n"<<"ans is:"<<ans<<endl; //查询时候的Trie树的样子 44 i--; 45 } 46 return ans; 47 } 48 49 int main() { 50 int T,n,a[MX]; 51 long long ans; 52 scanf("%d",&T); 53 while(T--) { 54 ans=0; 55 root.next[0]=NULL; 56 root.next[1]=NULL; 57 scanf("%d",&n); 58 for(int i=0; i<n; i++) { 59 scanf("%d",&a[i]); 60 BuildTrie(a[i]); 61 } 62 //cout<<"YES1\n"; 63 for(int i=0; i<n; i++) { 64 ans=max(ans,Query(a[i])); 65 } 66 // cout<<"YES2\n"; 67 printf("%I64d\n",ans); 68 } 69 return 0; 70 }