洛谷P3812 【模板】线性基(异或最大值)

题目背景
这是一道模板题。

题目描述
给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大。

输入格式
第一行一个数n,表示元素个数

接下来一行n个数

输出格式
仅一行,表示答案。

输入输出样例
输入 #1复制
2
1 1
输出 #1复制
1
说明/提示
1 \leq n \leq 50, 0 \leq S_i \leq 2 ^ {50}1≤n≤50,0≤S
i

≤2
50

具体讲解可以参考
XOR HDU - 3949(线性基/高斯消元/异或第k大) ACWING210. 异或运算

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;

ll f[105];
int p,cnt;

void insert(ll x)
{
    for(int i = 63;i >= 0;i--)
    {
        if((x >> i) & 1)//从高位到低位
        {
            if(!f[i])//第i位没有,赋值为x
            {
                f[i] = x;
                break;
            }
            x ^= f[i];//第i位有,去掉x的第i位
        }
    }
}

void build()
{
    for(int i = 0;i <= 63;i++)//高斯消元
    {
        for(int j = i + 1;j <= 63;j++)
        {
            if((f[j] >> i) & 1)f[j] ^= f[i];
        }
    }
    cnt = 0;
    for(int i = 0;i <= 63;i++)
    {
        if(f[i])
            f[cnt++] = f[i];
    }
}

ll query()
{
    ll res = 0;
    for(int i = 63;i >= 0;i--)
    {
        res = max(res,res ^ f[i]);
    }
    return res;
}

int main()
{
    
    int n;scanf("%d",&n);
    for(int i = 1;i <= n;i++)
    {
        ll x;scanf("%lld",&x);
        insert(x);
    }
    build();
    printf("%lld\n",query());
    
    return 0;
}


发布了697 篇原创文章 · 获赞 22 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/104302846