HDU 4825 Trie樹 異或樹!
阿新 • • 發佈:2017-07-22
釋放內存 情況 %d 前綴 out ble 證明 rip -s
Input
輸入包含若幹組測試數據,每組測試數據包含若幹行。
輸入的第一行是一個整數T(T < 10),表示共有T組數據。
每組數據的第一行輸入兩個正整數N,M(<1=N,M<=100000),接下來一行,包含N個正整數,代表 Zeus 的獲得的集合,之後M行,每行一個正整數S,代表 Prometheus 詢問的正整數。所有正整數均不超過2^32。
對於每個詢問,輸出一個正整數K,使得K與S異或值最大。
Sample Output
Case #1:
4
3
Case #2:
4
先聲明自己智障的看錯輸出的結果,以為輸出最大的異或後的值,誰知道與哪個數異或後的值最大,就輸出那個數,尷尬還以為樣例錯了。。。
字典樹這樣玩真的好酷炫,我是看了用字典樹才想到怎麽寫慚愧,這樣真的好巧妙,利用了字典樹前綴和的思想在O(len)的時間就能算出結果!
將每個數按二進制33位不夠得話高位補零,從高到低位存入字典樹中,其實就是一顆只含01的字典樹。
之所以由高到低是由於高位決定數的大小(貪心思想),對於讀入的每個數也按33位在樹上匹配,在滿足條件的情況下盡可能的選擇與bit不相同的位置走,
這樣答案就會最大,最後輸出ans^num就是原來的數!
可能動態鍵樹釋放內存的操作時間挺慢的跑700+ms,我看靜態數組都是200左右
Xor Sum
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 2403 Accepted Submission(s): 1041
輸入的第一行是一個整數T(T < 10),表示共有T組數據。
每組數據的第一行輸入兩個正整數N,M(<1=N,M<=100000),接下來一行,包含N個正整數,代表 Zeus 的獲得的集合,之後M行,每行一個正整數S,代表 Prometheus 詢問的正整數。所有正整數均不超過2^32。
Output 對於每組數據,首先需要輸出單獨一行”Case #?:”,其中問號處應填入當前的數據組數,組數從1開始計算。
對於每個詢問,輸出一個正整數K,使得K與S異或值最大。
Sample Input 2 3 2 3 4 5 1 5 4 1 4 6 5 6 3
1#include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 5 struct node 6 { 7 node *child[2]; 8 node(){child[0]=child[1]=NULL;} 9 }; 10 node *root; 11 void Clear(node *p) 12 { 13 if(p==NULL) return; 14 for(int i=0;i<2;++i){ 15 if(p->child[i]!=NULL) Clear(p->child[i]); 16 } 17 delete p; 18 } 19 void add(LL num) 20 { 21 node *p=root; 22 int i,bit; 23 for(i=32;i>=0;--i){ 24 bit=(num&((LL)1<<i))?1:0; 25 if(p->child[bit]==NULL) 26 p->child[bit]=new node(); 27 p=p->child[bit]; 28 } 29 } 30 LL solve(LL num) 31 { 32 node *p=root; 33 int i,bit[2]; LL ans=0; 34 for(i=32;i>=0;--i){ 35 bit[0]=(num&((LL)1<<i))?1:0; 36 if(p->child[bit[0]^1]!=NULL){ 37 p=p->child[bit[0]^1]; 38 bit[1]=1; 39 } 40 else {p=p->child[bit[0]];bit[1]=0;} 41 if(bit[1]) ans+=((LL)1<<i); 42 } 43 return ans; 44 } 45 int main() 46 { 47 int T,N,M,i,j,k=0; 48 LL n; 49 cin>>T; 50 while(T--){root=new node(); 51 cin>>N>>M; 52 for(i=1;i<=N;++i){ 53 scanf("%lld",&n); 54 add(n); 55 }printf("Case #%d:\n",++k); 56 for(i=1;i<=M;++i){ 57 scanf("%lld",&n); 58 printf("%lld\n",n^solve(n)); 59 } 60 Clear(root); 61 } 62 return 0; 63 }
HDU 4825 Trie樹 異或樹!