http://acm.hdu.edu.cn/showproblem.php?pid=6625
题意很简单不说了。
直接说怎么做,首先建两颗字典树,把a和b数组都放进去。
然后想了想是贪心,然后想了很多比如dfs还写了很久,最后是选择了对两颗字典树同时进行BFS.
分为四个方向,两颗树都是1,两颗树都是0,一颗0一颗1,一颗1一颗0.
这四个方向,优先满足1和0;
然后这个可能写着巨麻烦,我写错了很多发。。。。。其实先前有一个稍微简单的就可以过,但不过还是有点不安全。
首先来一个看着容易一点,感觉有一点不安全的代码
#include "bits/stdc++.h"
using namespace std;
const double eps = 1e-6;
#define reg register
#define lowbit(x) x&-x
#define pll pair<ll,ll>
#define pii pair<int,int>
#define fi first
#define se second
#define makp make_pair
#define cp complex<double>
int dcmp(double x) {
if (fabs(x) < eps) return 0;
return (x > 0) ? 1 : -1;
}
typedef long long ll;
typedef unsigned long long ull;
const ull hash1 = 201326611;
const ull hash2 = 50331653;
const ll N = 3300000 + 10;
const int M = 1000000;
const int inf = 0x3f3f3f3f;
const ll mod = 998244353;
const double PI = acos(-1.0);
struct Trie {
int nxt[N][2], cnt[N * 2], tot, root;
void init() {
tot = 1, root = 1;
nxt[root][0] = nxt[root][1] = 0;
cnt[root] = 0;
}
void Insert(int x) {
int u = root;
cnt[u]++;
for (int i = 31; i >= 0; i--) {
int idx = (x >> i) & 1;
if (nxt[u][idx] == 0) {
nxt[u][idx] = ++tot;
nxt[tot][1] = nxt[tot][0] = 0;
cnt[tot] = 0;
}
u = nxt[u][idx];
cnt[u]++;
}
}
} ta, tb;
int n, a[N], b[N];
vector<ll> v;
struct node {
int l, r, cnt, dep;
ll val;
};
queue<node> qu;
void bfs() {
while (!qu.empty()) qu.pop();
qu.push(node{1, 1, n, 0, 0});
while (!qu.empty()) {
node now = qu.front();
qu.pop();
if (now.dep == 32) {
for (int i = 1; i <= now.cnt; i++) {
v.push_back(now.val);
}
continue;
}
int la = ta.nxt[now.l][0];
int ra = ta.nxt[now.l][1];
int lb = tb.nxt[now.r][0];
int rb = tb.nxt[now.r][1];
int cnt = min(ta.cnt[la], tb.cnt[lb]);
if (cnt != 0 && la != 0 && lb != 0) {
ta.cnt[la] -= cnt;
tb.cnt[lb] -= cnt;
qu.push(node{la, lb, cnt, now.dep + 1, now.val});
}
cnt = min(ta.cnt[ra], tb.cnt[rb]);
if (cnt != 0 && ra != 0 && rb != 0) {
ta.cnt[ra] -= cnt;
tb.cnt[rb] -= cnt;
qu.push(node{ra, rb, cnt, now.dep + 1, now.val});
}
cnt = min(ta.cnt[la], tb.cnt[rb]);
if (cnt != 0 && la != 0 && rb != 0) {
ta.cnt[la] -= cnt;
tb.cnt[rb] -= cnt;
ll val = now.val | (1LL << (31 - now.dep));
qu.push(node{la, rb, cnt, now.dep + 1, val});
}
cnt = min(ta.cnt[ra], tb.cnt[lb]);
if (cnt != 0 && ra != 0 && lb != 0) {
ta.cnt[ra] -= cnt;
tb.cnt[lb] -= cnt;
ll val = now.val | (1LL << (31 - now.dep));
qu.push(node{ra, lb, cnt, now.dep + 1, val});
}
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
ta.init(), tb.init();
v.clear();
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
ta.Insert(a[i]);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
tb.Insert(b[i]);
}
bfs();
sort(v.begin(), v.end());
cout << v[0];
for (int i = 1; i < v.size(); i++) {
printf(" %lld", v[i]);
}
printf("\n");
}
return 0;
}
接下来就是一个巨恶心的代码。
#include "bits/stdc++.h"
using namespace std;
const double eps = 1e-6;
#define reg register
#define lowbit(x) x&-x
#define pll pair<ll,ll>
#define pii pair<int,int>
#define fi first
#define se second
#define makp make_pair
#define cp complex<double>
int dcmp(double x) {
if (fabs(x) < eps) return 0;
return (x > 0) ? 1 : -1;
}
typedef long long ll;
typedef unsigned long long ull;
const ull hash1 = 201326611;
const ull hash2 = 50331653;
const ll N = 6000000 + 10;
const int M = 1000000;
const int inf = 0x3f3f3f3f;
const ll mod = 998244353;
const double PI = acos(-1.0);
struct Trie {
int nxt[N][2], cnt[N * 2], tot, root;
void init() {
tot = 1;
root = newnode();
}
int newnode() {
nxt[tot][0] = nxt[tot][1] = 0;
cnt[tot] = 1;
return tot++;
}
void Insert(int x) {
int u = root;
cnt[u]++;
for (int i = 29; i >= 0; i--) {
int idx = (x >> i) & 1;
if (nxt[u][idx] == 0) {
nxt[u][idx] = newnode();
} else {
cnt[nxt[u][idx]]++;
}
u = nxt[u][idx];
}
}
} ta, tb;
int n, a[N], b[N];
vector<ll> v;
struct node {
int l, r, cnt, dep;
ll val;
};
void bfs(int n) {
queue<node> qu;
qu.push(node{1, 1, n, 0, 0});
while (!qu.empty()) {
node now = qu.front();
qu.pop();
if (now.dep == 30) {
for (int i = 1; i <= now.cnt; i++) {
v.push_back(now.val);
}
continue;
}
int cnt = now.cnt;
int la = ta.nxt[now.l][0];
int ra = ta.nxt[now.l][1];
int lb = tb.nxt[now.r][0];
int rb = tb.nxt[now.r][1];
int nla = ta.cnt[la];
int nlb = tb.cnt[lb];
int nra = ta.cnt[ra];
int nrb = tb.cnt[rb];
int cnt00 = min(cnt, min(nla, nlb));
cnt -= cnt00;
int cnt11 = min(cnt, min(nra, nrb));
cnt -= cnt11;
nla -= cnt00;
nlb -= cnt00;
nra -= cnt11;
nrb -= cnt11;
if (cnt00) {
qu.push(node{la, lb, cnt00, now.dep + 1, now.val});
}
if (cnt11) {
qu.push(node{ra, rb, cnt11, now.dep + 1, now.val});
}
int cnt01 = min(cnt, min(nla, nrb));
cnt -= cnt01;
int cnt10 = min(cnt, min(nra, nlb));
cnt -= cnt10;
nla -= cnt01;
nlb -= cnt10;
nra -= cnt10;
nrb -= cnt01;
if (cnt01) {
ll val = now.val | (1LL << (29 - now.dep));
qu.push(node{la, rb, cnt01, now.dep + 1, val});
}
if (cnt10) {
ll val = now.val | (1LL << (29 - now.dep));
qu.push(node{ra, lb, cnt10, now.dep + 1, val});
}
ta.cnt[la] = nla;
ta.cnt[ra] = nra;
tb.cnt[lb] = nlb;
tb.cnt[rb] = nrb;
}
}
int main() {
int T;
scanf("%d", &T);
///cin >> T;
while (T--) {
ta.init(), tb.init();
v.clear();
scanf("%d", &n);
///cin >> n;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
///cin >> a[i];
ta.Insert(a[i]);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
///cin >> b[i];
tb.Insert(b[i]);
}
bfs(n);
sort(v.begin(), v.end());
///printf("%d", v[0]);
cout << v[0];
for (int i = 1; i < v.size(); i++) {
///printf(" %d", v[i]);
cout << " " << v[i];
}
///printf("\n");
cout << endl;
}
return 0;
}