HDU 4825 Xor Sum

Xor Sum

http://acm.hdu.edu.cn/showproblem.php?pid=4825

分析:

  01trie。

  对每个数按长度从高位到低位建一条链,每个边上表示0/1,每次优先走不同的。每个数深度都是32,所以查询的时候走32步就行,并且每个点有边能够到达的点一定至少一个出边。

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<cctype>
 7 #include<set>
 8 #include<vector>
 9 #include<queue>
10 #include<map>
11 #define fi(s) freopen(s,"r",stdin);
12 #define fo(s) freopen(s,"w",stdout);
13 using namespace std;
14 typedef long long LL;
15 
16 inline LL read() {
17     LL x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
18     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
19 }
20 
21 int ch[3200005][2];
22 LL val[3200005];
23 int Index = 1, nowCase;
24 
25 void Insert(LL x) {
26     int u = 1;
27     for (int i=32; i>=0; --i) {
28         int c = (x >> i) & 1; // int c = x & (1 << i) !!!
29         if (!ch[u][c]) ch[u][c] = ++Index;
30         u = ch[u][c];
31     }
32     val[u] = x;
33 }
34 LL query(LL x) {
35     int u = 1;
36     for (int i=32; i>=0; --i) { // 32步,到叶子节点 
37         int c = (x >> i) & 1; 
38         if (ch[u][!c]) u = ch[u][!c]; // 优先走不同的 
39         else u = ch[u][c]; // 顺着存在的边走 
40     }
41     return val[u];
42 }
43 void solve() { 
44     printf("Case #%d:\n",++nowCase);
45     int n = read(), m = read();
46     for (int i=1; i<=n; ++i) {
47         LL x = read(); Insert(x);
48     }
49     for (int i=1; i<=m; ++i) {
50         LL x = read();
51         printf("%lld\n", query(x));
52     }
53     memset(ch, 0, sizeof(ch));
54     memset(val, 0, sizeof(val));
55     Index = 1;
56 }
57 int main() {
58     int T = read();
59     while (T--) solve(); 
60     return 0;
61 }

 

posted @ 2018-09-30 21:22  MJT12044  阅读(206)  评论(0编辑  收藏  举报