hdu5536 Chip Factory xor,字典树
Chip Factory
Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 280 Accepted Submission(s): 158
Problem 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
看到异或就应该想到字典树。。。
注意用siz来处理删除,而不要直接删除结点。
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=(1<<29); const double EPS=0.000000001; const double Pi=acos(-1.0); struct Trie { int ch[2]; int siz; void debug() { printf("lch=%2d rch=%2d siz=%2d\n",ch[1],ch[0],siz); } };Trie tr[maxn];int p;int rt; int n,a[maxn]; int newnode() { tr[++p].siz=0; tr[p].ch[0]=tr[p].ch[1]=-1; return p; } void Init() { rt=0; tr[rt].ch[0]=tr[rt].ch[1]=-1; tr[rt].siz=0; p=0; } void Insert(int t) { int k=rt; tr[k].siz++; int c; for(int i=30;i>=0;i--){ if(t&(1<<i)) c=1; else c=0; if(tr[k].ch[c]==-1) tr[k].ch[c]=newnode(); k=tr[k].ch[c]; tr[k].siz++; } } void Delete(int t) { int k=rt; tr[k].siz--; int c; for(int i=30;i>=0;i--){ if(t&(1<<i)) c=1; else c=0; k=tr[k].ch[c]; tr[k].siz--; } } int query(int t) { int k=rt; int res=0; for(int i=30;i>=0;i--){ if(t&(1<<i)){ if(tr[k].ch[0]==-1||tr[tr[k].ch[0]].siz==0){ k=tr[k].ch[1]; } else{ k=tr[k].ch[0]; res|=(1<<i); } } else{ if(tr[k].ch[1]==-1||tr[tr[k].ch[1]].siz==0){ k=tr[k].ch[0]; } else{ k=tr[k].ch[1]; res|=(1<<i); } } } return res; } int main() { freopen("in.txt","r",stdin); int T;cin>>T; while(T--){ scanf("%d",&n); Init(); REP(i,1,n) scanf("%d",&a[i]),Insert(a[i]); int ans=0; REP(i,1,n){ REP(j,i+1,n){ Delete(a[i]);Delete(a[j]); int tmp=query(a[i]+a[j]); ans=max(ans,tmp); Insert(a[i]);Insert(a[j]); } } cout<<ans<<endl; } return 0; }