题意:给你两个数组,对于每个ai,在b数组中找到一个元素与其异或,得到的值为ci,同时删除bi,然后让你输出组成字典序最小c数组
题解:裸的01字典树,对于每个ai,找能和ai异或出最小值的bi即可,暴力超时,所以可将每个bi插入字典树中,因为每次找到一个bi后要删除bi,但是对于删除操作我觉得过于繁琐,因此我是标记每个节点出现的次数,这样就能无脑不重复的找到当前最佳的bi(ps:比赛时死于sum数组的清空,为什么就不能延长个5分钟?->还是太菜)
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 300005
ll a[maxn],b[maxn],n,ans[maxn],siz,cnt[maxn*50][2];
ll sum[maxn*50];
void insert(ll x)
{
int now=0;
for(ll i=32;i>=0;i--)
{
ll p=0;
if(x&(1ll<<i))
p=1;
if(!cnt[now][p])
cnt[now][p]=++siz;
sum[cnt[now][p]]++;
now=cnt[now][p];
}
}
void work(int id,ll x)
{
int now=0;ll res=0;
for(ll i=32;i>=0;i--)
{
ll p=0;
if(x&(1ll<<i)) p=1;
if(sum[cnt[now][p]]==0)
res+=(1ll<<i),p=1-p;
sum[cnt[now][p]]--;
now=cnt[now][p];
}
ans[id]=res;
}
int main(void)
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
{
scanf("%lld",&b[i]);
insert(b[i]);
}
for(int i=1;i<=n;i++)
work(i,a[i]);
for(int i=1;i<=n;i++)
printf("%lld ",ans[i]);
printf("\n");
return 0;
}