Codeforces Round #470 D. Perfect Security(字典树)
http://codeforces.com/contest/948/problem/D
题意:给你两个数组A[]、P[](两个数组元素个数一样多),让你求两个数组中Ai异或Pj的最小值(两个数组中的元素只能取一次);
分析:仔细一看其实就是字典树,我们把P[]数组建立成字典树,用A[]数组中的每一位元素去匹配字典树,取最小值。
#include<cstdio>
using namespace std;
const int MAX=2;
const int maxn=3e5+100;
int A[maxn];
int tot=0;
struct Trie
{
int l,r;///左边为0,右边为1
int nl,nr;///0的个数和1的个数
}a[32*maxn];
void Insert(int x)
{
int id=0;
for(int i=29; i>=0; i--)
{
if(x&(1<<i))///x的二进制表示的第i位数为1
{
a[id].nr++;
if(a[id].r!=-1)
id=a[id].r;
else
{
tot++;
a[id].r=tot;
a[tot].l=-1;
a[tot].r=-1;
a[tot].nr=0;
a[tot].nl=0;
id=tot;
}
}
else///第i位为0
{
a[id].nl++;
if(a[id].l!=-1)
id=a[id].l;
else
{
tot++;
a[id].l=tot;
a[tot].l=-1;
a[tot].r=-1;
a[tot].nr=0;
a[tot].nl=0;
id=tot;
}
}
}
}
int Find(int x)
{
int id=0;
int ans=0;
for(int i=29; i>=0; i--)
{
if(x&(1<<i))///1;
{
if(a[id].nr!=0)
{
a[id].nr--;
id=a[id].r;
}
else
{
a[id].nl--;
ans=ans+(1<<i);
id=a[id].l;
}
}
else
{
if(a[id].nl)
{
a[id].nl--;
id=a[id].l;
}
else
{
a[id].nr--;
ans=ans+(1<<i);
id=a[id].r;
}
}
}
return ans;
}
int main()
{
int N;
scanf("%d",&N);
a[0].l=a[0].r=-1;
a[0].nl=a[0].nr=0;
for(int i=1; i<=N; i++)
{
scanf("%d",&A[i]);
}
for(int i=1; i<=N; i++)
{
int x;
scanf("%d",&x);
Insert(x);
}
for(int i=1; i<=N; i++)
printf("%d ",Find(A[i]));
return 0;
}

浙公网安备 33010602011771号