【LOJ 10050】The XOR Largest Pair【Trie】

题目大意:

题目链接:https://loj.ac/problem/10050
求一个数列中的任意两个数字亦或的最大值。


思路:

如果给出一个数字,求一个不比它位数大的数使得这两个数亦或的值最大,那么这个数应该取多少?
我们知道如果这个数转化为二进制后为100101101,那么亦或后最大值肯定是111111111,那么当另外一个数是011010010时,才能使他们的亦或值最大。
那么就构造一个 T r i e ,将每个数转化为二进制之后都扔进 T r i e 里,然后对于每一个数,再将它取反,并与 T r i e 比较,如果有相同的就走相同的,否则就走不同的。


代码:

#include <cstdio>
#include <algorithm>
#define M 5000005
#define up 30
using namespace std;

int n,x,y,k,tot=1,trie[M][2],d[M],z,ans;

void insert(int x)  //插入
{
    int p=1;
    for (int i=up;i>=0;i--)
    {
        int id=(x>>i)&1;  //取反
        if (!trie[p][id]) trie[p][id]=++tot;  //新建结点
        p=trie[p][id];
    }
}

int find(int x)  //查找
{
    int p=1,sum=0; 
    for (int i=up;i>=0;i--)
    {
        int id=(x>>i)&1;
        if (trie[p][id^1])  //取反
        {
            sum=(sum<<1)|1;
            p=trie[p][id^1];
        }
        else if (trie[p][id])  //不取反
         {
            sum<<=1;
            p=trie[p][id];
         }
    }
    return sum; 
}

int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
     scanf("%d",&d[i]),insert(d[i]);
    for (int i=1;i<=n;i++)
        ans=max(ans,find(d[i]));
    printf("%d",ans);
}

猜你喜欢

转载自blog.csdn.net/SSL_ZYC/article/details/81782057
今日推荐