【trie樹】Xor Sum


HDU 4825 Xor Sum

tql!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

我以為trie樹真的只是單純的處理字符串問題

orz是我天真了(呸!就是做題少!!


很多異或和問題都可以用trie樹解決

思路:

  1. 以0/1代替傳統trie樹中的字母, 先以讀入的數字(分解二進制)建立trie樹
  2. 異或:相同為0不同為1
  3. 將詢問的數字分解二進制,優先選擇與該位不同的,使異或值盡可能大(從高位開始), 如果沒有, 則走與該位相同的
  4. WA了很久居然是因為v數組沒有*32 QAQAQAQ //真。數組開小見祖宗
  5. 這個題我覺得還是很妙的qwq  Mark一下qwq

代碼qwq

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #define ll long long
 5 using namespace std;
 6 const int sz = 100010;
 7 int n, m, t, tot = 0;
 8 int trie[sz*32][2], v[sz*32];
 9 void insert(ll x) {
10     int root = 0;
11     for(int i = 32; i >= 0; i--) {
12         int id = (x>>i)&1;
13         if(!trie[root][id]) trie[root][id] = ++tot;
14         root = trie[root][id];
15     }
16     v[root] = x;
17 }
18 ll query(ll x) {
19     int root = 0;
20     for(int i = 32; i >= 0; i--) {
21         int id = (x>>i)&1;
22         if(trie[root][id^1]) root = trie[root][id^1];
23         else root = trie[root][id];
24     }
25     return v[root];
26 }
27 int main() {
28     scanf("%d", &t);
29     for(int k = 1; k <= t; k++) {
30         memset(trie, 0, sizeof(trie));
31         scanf("%d%d", &n, &m);
32         for(int i = 1; i <= n; i++) {
33             int d;
34             scanf("%d", &d);
35             insert(d);
36         }
37         printf("Case #%d:\n",k);
38         for(int i = 1; i <= m; i++) {
39             ll d;
40             scanf("%lld", &d);
41             printf("%lld\n", query(d));
42         }
43     }
44     return 0;
45 }

 

//還有, 如果root初始為1  tot一定也要初始為1 !!!!!!!!!!!(其實初始為0比較好, 玄學變快QAQ)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM