题意

给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大。
\(1≤n≤50,0≤S_i≤2^{50}\)

分析

模板题。
推荐一篇好博客
现在我来证明一下线性基的性质。

性质

这说的线性基是真正的线性基,不是程序里面的。

  1. 设线性基的异或集合中不存在0。
    这个是个构造,不用证明。数集T本身就是线性基,而它的异或集合中当然存在0。
  2. 线性基的异或集合中每个元素的异或方案唯一,其实这个跟性质1是等价的。
    如果异或方案有多种,那么这些方案去掉公共部分后异或起来就是0,与性质1矛盾。
  3. 线性基中元素互相异或,异或集合不变。
    考虑把这两个异或了的两个元素a,b提出来,剩下的组合,把这两个元素的贡献加入组合中,无论是否异或贡献都是a^b,a,b,0这4中情况
  4. 线性基二进制最高位互不相同。
    这也是一个构造。如果原集有两个最高位相同,那么异或一下就不同了。由于性质3,异或集合不变,所以新的这个集合还是线性基。
  5. 如果线性基是满的,它的异或集合为\([1,2^n-1]\)。
    没什么好说的。

标准化

就是querykth那样的构造,一定可以把线性基造成每个元素只有最高位为1的为1的集合。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x)
{
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-'0',ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

const int MAXB=51;
struct LB
{
    ll d[MAXB],p[MAXB];
    int cnt;

    LB()=default;

    bool insert(ll x)
    {
        for(int i=MAXB-1;i>=0;--i)
            if(x&(1LL<<i))
            {
                if(!d[i])
                {
                    d[i]=x;
                    break;
                }
                x^=d[i];
            }
        return x>0;
    }

    ll qmax()
    {
        ll res=0;
        for(int i=MAXB-1;i>=0;--i)
            if((res^d[i])>res)
                res^=d[i];
        return res;
    }

    ll qmin()
    {
        for(int i=0;i<MAXB;++i)
            if(d[i])
                return d[i];
        return 0;
    }

    void rebuild()
    {
        for(int i=MAXB-1;i>=0;--i)
            for(int j=i-1;j>=0;--j)
                if(d[i]&(1LL<<j))
                    d[i]^=d[j];
        cnt=0;
        for(int i=0;i<MAXB;++i)
            if(d[i])
                p[cnt++]=d[i];
    }

    ll qkth(ll k)
    {
        rebuild();
        if(k>=(1LL<<cnt))
            return -1;
        ll res=0;
        for(int i=cnt-1;i>=0;--i)
            if(k&(1LL<<i))
                res^=p[i];
        return res;
    }
}T;

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int n;
    read(n);
    while(n--)
    {
        static ll x;
        read(x);
        T.insert(x);
    }
    printf("%lld\n",T.qmax());
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

LG3812 【模板】线性基的更多相关文章

  1. [P3812][模板]线性基

    解题关键:求异或最大值.线性基模板题. 极大线性无关组的概念. 异或的值域相同. #include<cstdio> #include<cstring> #include< ...

  2. LG3812 「模板」线性基 线性基

    问题描述 LG3812 题解 线性基是一类擅长解决异或问题的数据结构(也不算数据结构吧...就是一种玄学的东西) 对于数列 \(a\) ,它的线性基 \(d\) 为 出现 \(1\) 的最高位在第 \ ...

  3. 线性基【p4570】 [BJWC2011]元素

    题目描述-->p4570 [BJWC2011]元素 题目大意 给定一些矿石的编号与价值,我们想要得到最大的价值和,并且选定物品的编号异或之和不为0. 分析 线性基就不多bb了,来这里->p ...

  4. P3812 【模板】线性基

    P3812 [模板]线性基 理解 :线性基 类似于 向量的极大无关组,就是保持原来所有数的异或值的最小集合, 求解过程也类似,可以 O( 60 * n )的复杂度求出线性基,线性基有许多性质,例如 线 ...

  5. 洛谷P3812 【模板】线性基 [线性基]

    题目传送门 线性基 题目描述 给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大. 输入输出格式 输入格式: 第一行一个数n,表示元素个数 接下来一行n个数 输出格式: 仅一行 ...

  6. 洛谷P3812 【模板】线性基

    题目背景 这是一道模板题. 题目描述 给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大. 输入输出格式 输入格式: 第一行一个数n,表示元素个数 接下来一行n个数 输出格式: ...

  7. 模板【洛谷P3812】 【模板】线性基

    P3812 [模板]线性基 给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大. code: #include <iostream> #include <cs ...

  8. 题解——洛谷P3812【模板】线性基

    学了下线性基 使用好像并不复杂 打了板子 但是要注意位运算优先级 #include <cstdio> #include <algorithm> #include <cst ...

  9. luogu 3812 【模板】 线性基

    线性基是一个支持在集合里插入数并查询最大子集异或值 #include<iostream> #include<cstdio> #include<cstring> #i ...

随机推荐

  1. C#正则过滤HTML标签并保留指定标签的方法

    本文实例讲述了C#正则过滤html标签并保留指定标签的方法.分享给大家供大家参考,具体如下: 这边主要看到一个过滤的功能: public static string FilterHtmlTag(str ...

  2. C#实现在应用程序间发送消息的方法示例

    本文实例讲述了C#实现在应用程序间发送消息的方法.分享给大家供大家参考,具体如下: 首先建立两个C#应用程序项目. 第一个项目包含一个Windows Form(Form1),在Form1上有一个But ...

  3. C# winform对话框用法大全

      对话框中我们常用了以下几种:1.文件对话框(FileDialog) 它又常用到两个: 打开文件对话框(OpenFileDialog) 保存文件对话(SaveFileDialog)2.字体对话框(F ...

  4. android--------微信 Tinker 热修复 (三)

    前面简单介绍了一下Tinker热修复的使用,包含debug和release,今天就来分享一下微信针对Tinker热修复提供的一个平台,TinkerPatch补丁管理后台. 1:什么是TinkerPat ...

  5. Asp.Net 高性能ORM框架——SqlSugar

    公司团队项目.产品已经完全抛弃EF,SqlSugar定位不是ORM,而是为了方便的让你去写Sql. SqlSugar 媲美原生ADO.NET的性能,语法简洁,并且支持 Json .Dynamic. L ...

  6. oaf 动态创建table vo (转)

    原文地址:如何动态创建table 需求: 因为系统中有几千个QA plan 但是不能手动创建几千个 质量收集页面所有需要根据 不同的plan 动态创建对应的 质量收集页面. 但是创建tabel 都要绑 ...

  7. ES6扩展运算符的几个小技巧

    es6扩展运算符,也就是...  ,作用是将一个数组转为用逗号分隔的参数序列. 那么问题来了,我们为啥要用这么奇怪的东东涅,当然因为它能大大提高我们的开发效率.所以,可别小看这三个点. 1.复制数组( ...

  8. 微信公众号平台开发(二)信息的分类.md

    在上一篇博客中,我们只是简单地与微信服务器建立了连接,接下来就是从微信服务器中接收信息了.在SecurityController中,我定义了两个方法(get和post).Get方法是我们用来与微信服务 ...

  9. UVALive 5844 dfs暴力搜索

    题目链接:UVAive 5844 Leet DES:大意是给出两个字符串.第一个字符串里的字符可以由1-k个字符代替.问这两个字符串是不是相等.因为1<=k<=3.而且第一个字符串长度小于 ...

  10. learning uboot switch to standby system using button

    pseudocode: If(reset_button was pressed ) { Change  uboot env bootslot^1 }