HDU4825 Xor Sum
题意:
询问\(m\)次,每次给出一个正整数\(k\),求数组中和他异或的最大值。
思路:
01字典树裸题,……但是我不会,特意学习一下。顺便回忆一下字典树
首先把数组中的每一个数,二进制存到字典树中,从高位开始,然后每次询问从上往下跑,尽量0走1,1走0。
注意数组的大小,-_-!!!!
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const int inf = 0X3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int mod = 1000000007;
typedef long long ll;
int n, m;
int a[N], val[32 * N];
int tri[32 * N][2];
int cnt;
void Insert(int x, int id) {
int u = 0;
for (int i = 31; i >= 0; i--) {
int bit = (x & (1 << i)) != 0; //int bit = (x & (1 << i)); 不太行
if (!tri[u][bit])
tri[u][bit] = cnt++;
u = tri[u][bit];
// cout << bit;
}
// cout << '\n';
val[u] = id;
}
int Query(int x) {
int u = 0;
for (int i = 31; i >= 0; i--) {
int bit = (x & (1 << i)) != 0;
if (tri[u][bit ^ 1])
u = tri[u][bit ^ 1];
else
u = tri[u][bit];
}
return a[val[u]];
}
int main() {
int T;
scanf("%d", &T);
for (int k = 1; k <= T; k++) {
scanf("%d %d", &n, &m);
cnt = 1;
memset(tri, 0, sizeof(tri));
memset(val, 0, sizeof(val));
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
Insert(a[i], i);
}
printf("Case #%d:\n", k);
for (int i = 1; i <= m; i++) {
int x;
scanf("%d", &x);
printf("%d\n", Query(x));
}
}
}
埋骨何须桑梓地,人生无处不青山