COJ 1216 异或最大值

来源:互联网 发布:鬼气凛然实体书淘宝 编辑:程序博客网 时间:2024/05/18 18:16

题目大意:

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


0 0
原创粉丝点击