http://codeforces.com/contest/948/problem/D
题意:给出两个序列a,b,找出b的某一种置换,求出字典序最小的序列c,满足ci=ai^bi。
对于每一个ai,我们只要找出序列b中可用元素中异或结果最小的那一个,就可以保证字典序最小了。对b中的每一个建立出
01字典树,再将ai代入查询即可。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxm = 300005;
int a[maxm], m, b[maxm];
typedef struct trie
{
trie *next[2];
int s;
trie()
{
next[0] = next[1] = NULL;
s= 0;
}
}trie;
trie *root = new trie;
void insert(int k)
{
trie *p = root, *q;
for (int i = 30;i >= 0;i--)
{
int id = (k&(1 << i)) != 0;
if (p->next[id] == NULL)
{
q = new trie;
p->next[id] = q;
p = p->next[id];
p->s++;
}
else
{
p = p->next[id];
p->s++;
}
}
}
int find(int k)
{
int ans = 0;
trie *p = root, *q, *temp;
for (int i = 30;i >= 0;i--)
{
int id = (k&(1 << i)) != 0;
if (p->next[id]!=NULL && p->next[id]->s > 0)
{
p->next[id]->s--;
p = p->next[id];
}
else
{
ans |= 1 << i;
p->next[id^1]->s--;
p = p->next[id^1];
}
}
return ans;
}
int main()
{
int n, i, j, k, sum;
scanf("%d", &n);
for (i = 1;i <= n;i++)
scanf("%d", &a[i]);
for (i = 1;i <= n;i++)
{
scanf("%d", &b[i]);
insert(b[i]);
}
for (i = 1;i <= n;i++)
{
int ans = find(a[i]);
printf("%d ", ans);
}
printf("\n");
return 0;
}