HDU 4825 Xor Sum (trie树处理异或)

Xor Sum

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


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

 

分析

要求求出原集合中与所给的数异或值最大的数。

建立一颗trie树,左边是0,右边是1。将所有数放到trie树中。

那么,对于给定的数x,将x二进制分解,在trie中从高位往低位走,每一位最好是和x不同(异或:不同为1,相同为0)。

code

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 const int N = 5000100;
 7 
 8 inline char nc() {
 9     static char buf[100000],*p1=buf,*p2=buf;
10     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
11 }
12 inline int read() {
13     int x = 0,f = 1;char ch = nc();
14     for (; ch<'0'||ch>'9'; ch=nc()) if(x=='-')f=-1;
15     for (; ch>='0'&&ch<='9'; ch=nc()) x=x*10+ch-'0';
16     return x * f;
17 }
18 struct Trie{
19     int val[N],ch[N][2];
20     int cnt;
21     void init() {
22         memset(ch,0,sizeof(ch));
23         memset(val,0,sizeof(val));
24         cnt = 0;
25     }
26     void Insert(int x) {
27         int u = 0;
28         for (int i=31; i>=0; --i) {
29             int c = (x&(1<<i)) > 0;
30             if (!ch[u][c]) ch[u][c] = ++cnt;
31             u = ch[u][c];
32         }
33         val[u] = x;
34     }
35     int Query(int x) {
36         int u = 0;
37         for (int i=31; i>=0; --i) {
38             int c = (x&(1<<i))>0;
39             if (ch[u][!c]) u = ch[u][!c];
40             else if(ch[u][c]) u = ch[u][c]; // 
41         }
42         return val[u];
43     }
44 }t;
45 
46 int main () {
47     int T = read();
48     for (int Case=1; Case<=T; ++Case) {
49         t.init();
50         int n = read(),m = read();
51         for (int i=1; i<=n; ++i) {
52             int a = read();
53             t.Insert(a);
54         }
55         printf("Case #%d:\n",Case);
56         while (m--) {
57             int a = read();
58             printf("%d\n",t.Query(a));
59         }
60     }
61     return 0;
62 }
View Code

 

posted @ 2018-02-10 16:46  MJT12044  阅读(212)  评论(0编辑  收藏  举报