题目链接:https://cn.vjudge.net/problem/HDU-6625
题意:a和b两个数组n个数,数字任意组合异或,求得到c数组的字典序最小
题解:对于两个数组从高位到低位建立两个字典树,然后从高位到低位这样走,如果接下来的位两者都有的话,就走一样的,否则就走不一样的,就是一种贪心的策略。最后排一下序即可,鑫爷tql
#include <bits/stdc++.h>
using namespace std;
const int N = 100100;
struct node {
int nex[2];
int val;
}t[2][N * 32];
int tot[2];
int ans[N];
int n;
void insert(int x, int op) {
int p = 0, f;
for(int i = 29; i >= 0; i--) {
f = ((x >> i) & 1);
if(!t[op][p].nex[f] ) {
t[op][p].nex[f] = ++tot[op];
t[op][tot[op]].nex[0] = t[op][tot[op]].nex[1] = t[op][tot[op]].val = 0;
}
p = t[op][p].nex[f];
t[op][p].val++;
}
}
int query() {
int p0 = 0, p1 = 0;
int x = 0;
for(int i = 29; i >= 0; i--) {
if(t[0][t[0][p0].nex[0] ].val&& t[1][t[1][p1].nex[0] ].val) {
p0 = t[0][p0].nex[0];
t[0][p0].val--;
p1 = t[1][p1].nex[0];
t[1][p1].val--;
} else if(t[0][t[0][p0].nex[1] ].val&& t[1][t[1][p1].nex[1] ].val) {
p0 = t[0][p0].nex[1];
t[0][p0].val--;
p1 = t[1][p1].nex[1];
t[1][p1].val--;
} else if(t[0][t[0][p0].nex[1] ].val&& t[1][t[1][p1].nex[0] ].val) {
p0 = t[0][p0].nex[1];
t[0][p0].val--;
p1 = t[1][p1].nex[0];
t[1][p1].val--;
x += (1 << i);
} else {
p0 = t[0][p0].nex[0];
t[0][p0].val--;
p1 = t[1][p1].nex[1];
t[1][p1].val--;
x += (1 << i);
}
}
return x;
}
int main() {
int T;
int x;
scanf("%d", &T);
while(T--) {
tot[0] = tot[1] = 0;
t[0][0].nex[0] = t[0][0].nex[1] = t[0][0].val = 0;
t[1][0].nex[0] = t[1][0].nex[1] = t[1][0].val = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &x);
insert(x, 0);
}
for(int i = 1; i <= n; i++) {
scanf("%d", &x);
insert(x, 1);
}
for(int i = 1; i <= n; i++) {
ans[i] = query();
}
sort(ans + 1, ans + 1 + n);
for(int i = 1; i <= n; i++)
printf("%d%c", ans[i], " \n"[i == n]);
}
return 0;
}