zoukankan      html  css  js  c++  java
  • 线性基(解决子集异或和问题)

    适用:解决集合异或和问题(第k小异或,最大异或,能否异或和组成给定的数)

    用途:主要给个S集合,能通过动态插入每个数得到大小为log{max ai}的线性基B,而B中的所有情况异或和都唯一对应于S中的每个数

    注意:线性基中没有异或和为0的子集,也就是说当线性基集合小于S时,证明在S中有些集合异或和为0;

    模板题:https://vjudge.net/problem/SGU-275

    题意:求能异或和最大的值

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int M=60;
    struct LB{
        ll a[M+2];
        void init(int n){
            for(int i=0;i<=M;i++) a[i]=0;
        }
        void Insert(ll t){
            // 逆序枚举二进制位
            for (int j = M; j >= 0; j--){
                // 如果 t 的第 j 位为 0,则跳过
                if (!(t & (1ll << j))) continue;
    
                // 如果 a[j] != 0,则用 a[j] 消去 t 的第 j 位上的 1
                if (a[j]) t ^= a[j];
                else{
                    // 找到可以插入 a[j] 的位置
    
                    // 用 a[0...j - 1] 消去 t 的第 [0, j) 位上的 1
                    // 如果某一个 a[k] = 0 也无须担心,因为这时候第 k 位不存在于线性基中,不需要保证 t 的第 k 位为 0
                    for (int k = 0; k < j; k++) if (t & (1ll << k)) t ^= a[k];
    
                    // 用 t 消去 a[j + 1...L] 的第 j 位上的 1
                    for (int k = j + 1; k <= M; k++) if (a[k] & (1ll << j)) a[k] ^= t;
    
                    // 插入到 a[j] 的位置上
                    a[j] = t;
    
                    // 不要忘记,结束插入过程
                    return;
                }
    
                // 此时 t 的第 j 位为 0,继续寻找其最高位上的 1
            }
    
            // 如果没有插入到任何一个位置上,则表明 t 可以由 a 中若干个元素的异或和表示出,即 t 在 span(a) 中
        }
        ll getmax(){
            ll ans=0;
            for(int i=M;i>=0;i--)
                ans^=a[i];
            return ans;
        }
    }lb;
    int main(){
        int n;
        scanf("%d",&n);
        lb.init(n);
        for(int i=1;i<=n;i++){
            ll x;
            scanf("%lld",&x);
            lb.Insert(x);
        }
        printf("%lld
    ",lb.getmax());
        return 0;
    }
    View Code

    学习粗:https://oi.men.ci/linear-basis-notes/

  • 相关阅读:
    学机器学习,不会数据分析怎么行——数据可视化分析(matplotlib)
    关于 tensorflow-gpu 中 CUDA 和 CuDNN 版本适配问题
    人工智能学习资料
    JAVA Socket通信 打造属于自己的网盘
    在 Windows 10 中使用 OpenAI Spinning Up
    【LeetCode】回文串专题
    【LeetCode】45.跳跃游戏2
    【LeetCode】23.最大子序和
    【LeetCode】3. 无重复字符的最长子串(典型滑动窗口)
    【LeetCode】202.快乐数
  • 原文地址:https://www.cnblogs.com/starve/p/13802275.html
Copyright © 2011-2022 走看看