HDU 5536 Chip Factory(字典樹)
Chip Factory
Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 5258 Accepted Submission(s): 2358Problem Description
John is a manager of a CPU chip factory, the factory produces lots of chips everyday. To manage large amounts of products, every processor has a serial number. More specifically, the factory produces n chips today, the i-th chip produced this day has a serial number si. At the end of the day, he packages all the chips produced this day, and send it to wholesalers. More specially, he writes a checksum number on the package, this checksum is defined as below:
maxi,j,k(si+sj)⊕sk
which i,j,k are three different integers between 1 and n. And ⊕ is symbol of bitwise XOR. Can you help John calculate the checksum number of today?
Input
The first line of input contains an integer T indicating the total number of test cases. The first line of each test case is an integer n, indicating the number of chips produced today. The next line has n integers s1,s2,..,sn, separated with single space, indicating serial number of each chip. 1≤T≤1000 3≤n≤1000 0≤si≤109 There are at most 10 testcases with n>100
Output
For each test case, please output an integer indicating the checksum number in a line.
Sample Input
2 3 1 2 3 3 100 200 300
Sample Output
6 400
Source
與HDU4825類似
有關異或的題一定要先往2進位制上想,這道題不同的地方是要先在字典樹上刪除a[i]與a[j],在查詢與(a[i]+a[j])的和異或的最大值
#include <bits/stdc++.h> using namespace std; const int MAXN = 400005; struct Trie_node { int next[2]; int flag; void init() { next[0] = next[1] = 0; flag = 0; } }trie[MAXN]; int trie_n; void Insert(int num) { int root = 0,t,next; for(int i = 30; i >= 0; i--) { if(num & (1 << i)) t = 1; else t = 0; next = trie[root].next[t]; if(next == 0) { next = trie[root].next[t] = ++trie_n; } root = next; trie[root].flag++; } } void Delete(int num) { int root = 0,t; for(int i = 30; i >= 0; i--) { if(num & (1 << i)) t = 1; else t = 0; root = trie[root].next[t]; trie[root].flag--; } } int Query(int num) { int root = 0,t,next; for(int i = 30; i >=0; i--) { if(num & (1 << i)) t = 1; else t = 0; if(t == 1) { next = trie[root].next[0]; if(trie[next].flag > 0 && next) { root = trie[root].next[0]; } else { root = trie[root].next[1]; num ^= (1 << i); } } else { next = trie[root].next[1]; if(trie[next].flag > 0 && next) { root = trie[root].next[1]; num ^= (1 << i); } else { root = trie[root].next[0]; } } } return num; } int a[MAXN]; int main(void) { int T,n,ans; scanf("%d",&T); while(T--) { for(int i = 0; i <= trie_n; i++) { trie[i].init(); } trie_n = 0; scanf("%d",&n); for(int i = 0; i < n; i++) { scanf("%d",&a[i]); Insert(a[i]); } ans = 0; for(int i = 0; i < n; i++) { Delete(a[i]); for(int j = i + 1; j < n; j++) { Delete(a[j]); ans = max(ans,Query(a[i] + a[j])); Insert(a[j]); } Insert(a[i]); } printf("%d\n",ans); } return 0; }