COJ 1216 异或最大值

本文介绍了一种通过建立字母树来寻找数组中两数的最大异或值的方法,并提供了完整的C++代码实现。该方法利用贪心策略,在O(32*n)的时间复杂度内求解,适用于计算机科学中的算法竞赛及数据结构学习。

题目大意:

从N个数中选取两个数,使得异或值最大。

建立字母树,对于每个数贪心的找与它异或值最大的那个,复杂度为O(32 * n)。详情 参见莫涛PPT 《高斯消元解异或方程组》

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#define LL long long 
using namespace std;
const int MAXN = 3200010;
int Next[MAXN][2];
int End[MAXN];
int A[100010];
int root, L;
int newnode()
{
    for(int i=0;i<2;i++)
        Next[L][i] = -1;
    End[L] = -1;
    return L++;
}
int cal(int x)
{
    int cur = 0;
    for(int i=30;i;i--)
    {
        int k = ((1 << i) & x) ? 0 : 1;
        if(Next[cur][k] != -1) cur = Next[cur][k];
        else cur = Next[cur][1 - k];
    }
    //cout << cur << ' ' << End[cur] << Endl;
    return (x ^ End[cur]);
}
int main()
{
    int n, x;
    while(scanf("%d", &n)!=EOF)
    {
    L = 0, root = newnode();
    for(int i=1;i<=n;i++)
    {
        scanf("%d", &x);A[i] = x;
        int now = 0;
        for(int j=30;j;j--)
        {
            int k = ((1 << j) & x) ? 1 : 0;
            if(Next[now][k] == -1) Next[now][k] = newnode();
            now = Next[now][k];
        }
        End[now] = x;
       // cout << now << ' ' << End[now] << Endl;
    }
    int ans = 0;
    for(int i=1;i<=n;i++) ans = max(ans, cal(A[i]));
        printf("%d\n", ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值