COJ 1216 异或最大值

题目大意:

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

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

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


你可能感兴趣的:(各种异或)