HDU 4825 tire树

Xor Sum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 2505    Accepted Submission(s): 1076

Problem Description

Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?

Input

输入包含若干组测试数据,每组测试数据包含若干行。
输入的第一行是一个整数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

Sample Output

Case #1:

4

3

Case #2:

4

Source

2014年百度之星程序设计大赛 - 资格赛

题意:在集合当中找出一个正整数 k ,使得 k 与 k 的异或结果最大

题解:跑tire树

 1 #pragma comment(linker, "/STACK:102400000,102400000")
 2 #include <bits/stdc++.h>
 3 #include <cstdlib>
 4 #include <cstdio>
 5 #include <iostream>
 6 #include <cstdlib>
 7 #include <cstring>
 8 #include <algorithm>
 9 #include <cmath>
10 #include <cctype>
11 #include <map>
12 #include <set>
13 #include <queue>
14 #include <bitset>
15 #include <string>
16 #include <complex>
17 #define LL long long
18 #define mod 1000000007
19 using namespace std;
20 int t;
21 int n,m;
22 struct Tire
23 {
24     int T[3000006][3],sum[3000006];
25     int cou;
26     void init()
27     {
28         cou=1;
29         memset(T,0,sizeof(T));
30         memset(sum,0,sizeof(sum));
31     }
32     void inser(int num)
33     {
34         int h=0;
35         for(int i=31; i>=0; i--)
36         {
37             if(T[h][(num>>i)&1]==0)
38                 T[h][(num>>i)&1]=cou++;
39             h=T[h][(num>>i)&1];
40         }
41         sum[h]=num;
42     }
43     int ask(int num)
44     {
45         int  h=0;
46         for(int i=31; i>=0; i--)
47         {
48             int x=(num>>i)&1,sign=0;
49             if(x==0) sign=1;
50             if(T[h][sign]) h=T[h][sign];
51             else h=T[h][x];
52         }
53         return sum[h];
54     }
55 }tire;
56 int main()
57 {
58     scanf("%d",&t);
59     for(int k=1; k<=t; k++)
60     {
61         tire.init();
62         scanf("%d %d",&n,&m);
63         int exm;
64         for(int j=1; j<=n; j++)
65         {
66             scanf("%d",&exm);
67             tire.inser(exm);
68         }
69         printf("Case #%d:\n",k);
70         for(int j=1;j<=m;j++)
71         {
72             scanf("%d",&exm);
73             printf("%d\n",tire.ask(exm));
74         }
75     }
76     return 0;
77 }
时间: 2024-10-14 15:55:07

HDU 4825 tire树的相关文章

HDU 4825 字典树

HDU 4825 对于给定的查询(一个整数),求集合中和他异或值最大的值是多少 按位从高位往低位建树,查询时先将查询取反,然后从高位往低位在树上匹配,可以匹配不可以匹配都走同一条边(匹配表示有一个异或值为1的边,选择当然最好:不能匹配说明不存在一条异或值为1的边,那么只存在一条为0的边,也不得不选) 1 //#pragma comment(linker, "/STACK:1677721600") 2 #include <map> 3 #include <set>

HDU 4825 Trie树 异或树!

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 2403    Accepted Submission(s): 1041 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze

[HDU] 4825 (01字典树)

Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大.Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助.你能证明人类的智慧么? Input 输入包含若干组测试数据,每组测试数据

HDU 4825 Xor Sum(经典01字典树+贪心)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 1555    Accepted Submission(s): 657 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze

HDU 4825 Xor Sum 字典树+位运算

点击打开链接 Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 291    Accepted Submission(s): 151 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus

HDU 4825 Xor Sum(二进制的字典树,数组模拟)

题目 //居然可以用字典树...//用cin,cout等输入输出会超时 //这是从别处复制来的 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int node[3011111][2]; int tag,m,n,cas=0,T; long long one[64],allone,tmp; //0/1树的加数据操作,增加一个32的数 //其中如果当前位是0,则加左儿子,

Xor Sum HDU - 4825(01字典树)

Xor Sum HDU - 4825 (orz从之前从来没见过这种题 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 const int maxnode = 100010 * 32; 5 const int sigma = 2; 6 struct AC01{ 7 int ch[maxnode][sigma]; 8 LL val[maxnode]; 9 int sz; 10 void init(

Tire树入门专题

POJ 3630Phone List 题目连接:http://poj.org/problem?id=3630 题意:问是否有号码是其他号码的前缀. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<map> 5 using namespace std; 6 const int N=1e5+100; 7 struct Tire 8 { 9 int T[N][30]; 1

Chip Factory HDU - 5536 字典树(删除节点|增加节点)

题意: t组样例,对于每一组样例第一行输入一个n,下面在输入n个数 你需要从这n个数里面找出来三个数(设为x,y,z),找出来(x+y)^z(同样也可以(y+z)^1)的最大值 (“^”代表异或操作,即“相同为0,不同为1”) 题解: 这一道题和Xor Sum HDU - 4825很相似 因为异或运算的特性,我们最后要求最大值,那我们就对这n个数的二进制形式建一颗字典树.然后就暴力枚举是哪两个数相加,然后在字典树中把这两个数删掉.然后在处理完的字典树中查找那个能使结果尽可能大的第三个数(至于怎么