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;
}

 

posted @ 2018-03-16 17:29  孟加拉国  阅读(82)  评论(0编辑  收藏  举报