【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)

 

转载于:https://www.cnblogs.com/Hwjia/p/9798915.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值