nyoj - 947(Max Xor)字典树

来源:互联网 发布:高铁买票软件 编辑:程序博客网 时间:2024/06/05 01:19


题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=947


/**    你可以把所有的数字变成等长的二进制,当成字符串    然后建字典树,再枚举每个数把这个数的每一位取反去匹配    匹配的时候能匹配就尽量匹配,不能就走不同的分支    这样求出来的就是这个数能搞出来的最大的**/#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>using namespace std;typedef long long LL;LL a[100005],c[55];struct node{    int sum;    node *next[2];};struct node *root;struct node *build(){    struct node *p;    p=(struct node *)malloc(sizeof(struct node));    for(int i=0; i<2; i++)    {        p->next[i]=NULL;    }    return p;}void solve(LL s){    memset(c,0,sizeof(c));    int num = 50;    while(s)    {        c[num--] = s%2;        s/=2;    }}void insert(LL s){    solve(s);    struct node *p;    p=root;    for(int i=0; i<=50; i++)    {        if(p->next[c[i]]==NULL)            p->next[c[i]]=build();        p=p->next[c[i]];    }}LL find(LL s){    solve(s);    struct node *p;    p=root;    LL sum = 0;    for(int i=0; i<=50; i++)    {        if(p->next[!c[i]]==NULL)//尽量使高位为1,所以取反          {            sum = sum * 2;            p=p->next[c[i]];        }        else        {            sum = sum * 2 + 1;            p=p->next[!c[i]];        }    }    return sum;}int main(){    int n,i;    while(scanf("%d",&n)!=EOF)    {        root=build();        LL ans = 0;        for(i=0; i<n; i++)        {            scanf("%lld",&a[i]);            insert(a[i]);        }        for(i = 0; i < n; i++)            ans = max(find(a[i]),ans);        printf("%lld\n",ans);    }    return 0;}


0 0