对A和B分别建两棵trie树, 两边同时找, 尽量找相同的, 找到叶子节点时记录答案, 最后将答案排序输出.
#include<bits/stdc++.h>
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
return x*f;
}
const int N=3.5e6+28;
struct TRIE{
int ch[N][2],sum[N],val[N],tot;
int Ins(int x){
int p=1;
for(int i=31;i>=0;i--){
int v=((x&(1<<i))!=0);
if(!ch[p][v])ch[p][v]=++tot;
p=ch[p][v];
}
sum[p]++;
val[p]=x;
}
void Updata(int p){
sum[p]=sum[ch[p][0]]+sum[ch[p][1]];
if(sum[ch[p][0]]<=0)ch[p][0]=0;
if(sum[ch[p][1]]<=0)ch[p][1]=0;
}
void Dfs(int p=1){
if(val[p]!=-1)return;
if(ch[p][0])Dfs(ch[p][0]);
if(ch[p][1])Dfs(ch[p][1]);
Updata(p);
}
void format(){
for(int i=0;i<=tot;i++){
sum[i]=0;
val[i]=-1;
ch[i][0]=ch[i][1]=0;
}
tot=1;
}
stack<int>stk;
int Query(int x){
int p=1;
stk.push(p);
for(int i=31;i>=0;i--){
int v=((x&(1<<i))!=0);
if(ch[p][v])p=ch[p][v];
else p=ch[p][v^1];
stk.push(p);
}
stk.pop();
sum[p]--;
while(stk.size())Updata(stk.top()),stk.pop();
//printf("%d^%d=%d sum=%d
",val[p],x,val[p]^x,sum[p]);
return val[p]^x;
}
TRIE(){
memset(sum,0,sizeof(sum));
memset(val,-1,sizeof(val));
memset(ch,0,sizeof(ch));
tot=1;
}
}A,B;
int ans[N],cnt;
void format(){
A.format();
B.format();
cnt=0;
}
void dfs(int pa=1,int pb=1){
if(A.val[pa]!=-1){
ans[++cnt]=A.val[pa]^B.val[pb];
A.sum[pa]--,B.sum[pb]--;
return;
}
while(A.ch[pa][0]&&B.ch[pb][0]){
dfs(A.ch[pa][0],B.ch[pb][0]);
A.Updata(pa),B.Updata(pb);
}
while(A.ch[pa][1]&&B.ch[pb][1]){
dfs(A.ch[pa][1],B.ch[pb][1]);
A.Updata(pa),B.Updata(pb);
}
while(A.ch[pa][0]&&B.ch[pb][1]){
dfs(A.ch[pa][0],B.ch[pb][1]);
A.Updata(pa),B.Updata(pb);
}
while(A.ch[pa][1]&&B.ch[pb][0]){
dfs(A.ch[pa][1],B.ch[pb][0]);
A.Updata(pa),B.Updata(pb);
}
}
signed main(){
int t=read();
while(t--){
format();
int n=read();
for(int i=1;i<=n;i++){
int a=read();
A.Ins(a);
}
A.Dfs();
for(int i=1;i<=n;i++){
int b=read();
B.Ins(b);
}
B.Dfs();
dfs();
sort(ans+1,ans+n+1);
for(int i=1;i<=n;i++){
printf("%d",ans[i]);
if(i!=n)putchar(' ');
}
puts("");
}
return 0;
}