题意

给你两个序列 ,让你求的一种排列,使得得到的序列字典序最小

思路

贪心的选择匹配,使得最优。我们将,拆分后 , 贪心就可以方便地进行。枚举两串上,每一位上的数尽量使各位相异或后为即可选择出最合适的

实现

还是要用到我们的树来实现。先建立一棵基于 的二进制数的字典树,并记录各节点代表的元素出现的个数。然后传入每一个进行查找,从字典树的根部向下查找每一位,尽可能使得异或和为。若最优值在此位置个数为,选择另一值,使此位置选择的值数量,并进入下一层 , 继续进行查找。

代码

#include<bits/stdc++.h>
#define ll long long
const int N=1e7+5,INF=0x3f3f3f3f,mod=998244353;
using namespace std;

int n,num=1,py;
int a[N];
struct node
{
    int cnt,son[2];
}t[N];

inline int read()
{
    register int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}

int qpow(int a,int b)
{
    int ans=1;
    while(b){if(b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;}
    return ans;
}

void insert(int x)
{
    int now=1;
    t[1].cnt++;
    for(int i=30;i>=0;i--)
    {
        int nxt=(x>>i)&1;
        if(!t[now].son[nxt]) t[now].son[nxt]=++num;
        now=t[now].son[nxt];
        t[now].cnt++;
    }
}

int query(int x)
{
    int now=1,ans=0;
    for(int i=30;i>=0;i--) 
    {
        int nxt=(x>>i)&1;
        if(!t[t[now].son[nxt]].cnt) nxt=!nxt; 
        ans=(ans<<1)+nxt;
        now=t[now].son[nxt];
        t[now].cnt--;
    }
    return ans^x;
}

int main()
{
    n=read();
    for(int i=1;i<=n;i++)    a[i]=read();
    for(int i=1;i<=n;i++)    py=read(),insert(py);    
    for(int i=1;i<=n;i++)    printf("%d ",query(a[i])); 
    return 0;
}