【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