http://acm.hdu.edu.cn/showproblem.php?pid=6625
题目描述
There are three integer arrays a,b,c. The lengths of them are all N. You are given the full contents of a and b. And the elements in c is produced by following equation: c[i]=a[i] XOR b[i] where XOR is the bitwise exclusive or operation.
Now you can rearrange the order of elements in arrays a and b independently before generating the array c. We ask you to produce the lexicographically smallest possible array c after reordering a and b. Please output the resulting array c.
输入
The first line contains an integer T indicating there are T tests.
Each test consists of three lines. The first line contains one positive integer N denoting the length of arrays a,b,c. The second line describes the array a. The third line describes the array b.
* T≤1000
* 1≤N≤10^5
* integers in arrays a and b are in the range of [0,2^30).
* at most 6 tests with N>100
输出
For each test, output a line containing N integers, representing the lexicographically smallest resulting array c.
样例输入
复制样例数据
1 3 3 2 1 4 5 6
样例输出
4 4 7 建两棵字典树进行匹配,尽量走节点值相同的节点(同为0异为1,要使异或值相同,那就尽可能使同一位置上的数相同)
鑫爷tql
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e6;
const int maxc=2;
char s[66];
struct TRIE{
int Next[maxn][maxc];
int num[maxn];
//bool isw[maxn];//查询整个单词用
int root=1;
int tot=0;
int base;
void init(){
for(int i=0;i<=tot;i++) {
memset(Next[i],0,sizeof(Next[i]));
num[i]=0;
//isw[i]=false;
}
tot=1;
}
void add(char s[],int now){
int len=strlen(s);
for(int i=0;i<len;i++){
int c=s[i]-base;
if(!Next[now][c]){
Next[now][c]=++tot;
}
now=Next[now][c];
}
//isw[now]=true;//标记该单词末位字母的尾节点
}
bool find(char s[],int now){
int len=strlen(s);
for(int i=0;i<len;i++){
int c=s[i]-base;
if(!Next[now][c]) return false;
now=Next[now][c];
}
return true;
//查询整个单词时,应该return isw[now]
}
void addnum(int x,int now){
int p[35];
for(int i=0;i<30;i++){
p[i]=x&1;
x>>=1;
}
for(int i=29;i>=0;i--){
int c=p[i];
if(!Next[now][c]){
Next[now][c]=++tot;
}
now=Next[now][c];
num[now]++;
}
//isw[now]=true;
}
}a,b;
int q[maxn];
void solve(int pos){//匹配两棵字典树
int ra=1,rb=1;
int ans=0;
for(int i=29;i>=0;i--){
int a0=a.Next[ra][0],a1=a.Next[ra][1];
int b0=b.Next[rb][0],b1=b.Next[rb][1];
if(a0&&b0&&a.num[a0]&&b.num[b0]) {
a.num[a0]--;
b.num[b0]--;
ra=a0;
rb=b0;
continue;
}
else if(a1&&b1&&a.num[a1]&&b.num[b1]) {
a.num[a1]--;
b.num[b1]--;
ra=a1;
rb=b1;
continue;
}
else if(a0&&b1&&a.num[a0]&&b.num[b1]){
a.num[a0]--;
b.num[b1]--;
ra=a0;
rb=b1;
ans+=(1<<i);
continue;
}
else if(a1&&b0&&a.num[a1]&&b.num[b0]){
a.num[a1]--;
b.num[b0]--;
ra=a1;
rb=b0;
ans+=(1<<i);
continue;
}
}
q[pos]=ans;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
a.init();
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
a.addnum(x,1);
}
b.init();
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
b.addnum(x,1);
}
for(int i=1;i<=n;i++) solve(i);
sort(q+1,q+1+n);
for(int i=1;i<=n;i++)printf("%d%c",q[i]," \n"[i==n]);
}
return 0;
}