zoukankan      html  css  js  c++  java
  • 【数据结构】线性基

    参考题:https://www.luogu.com.cn/problem/P3812

    作用

    • 查询某个数是否能被一组数异或得到
    • 查询一组数能够异或的到的最大/小值,第k大值

    解释

    本质上就是作用在 (01) 串的高斯消元,只不过消元的途径是异或

    比如一组数(二进制):

    1010
    
    1100
    
    0011
    

    建立线性基的过程是:
    (egin{pmatrix} 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ end{pmatrix})

    对第一个数:
    从最高位开始扫,发现第一位就是 (0) ,故更新:

    (egin{pmatrix} 1 & 0 & 1 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ end{pmatrix})

    对第二个数:
    依然从最高位开始扫,发现第一位是 (1) ,所以第二个数要异或第一位对应的基底得到 (0110_{(2)}) ,继续扫,第二位是(0),故更新为:

    (egin{pmatrix} 1 & 0 & 1 & 0\ 0 & 1 & 1 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ end{pmatrix})

    类似的,对第三个数,可以更新矩阵得到:

    (egin{pmatrix} 1 & 0 & 1 & 0\ 0 & 1 & 1 & 0\ 0 & 0 & 1 & 1\ 0 & 0 & 0 & 0\ end{pmatrix})

    可以发现上面整个过程就是通过异或来进行高斯消元

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    const int N=55;
    
    ll base[N];
    
    int main(){
        int n; cin>>n;
        while(n--){
            ll k; cin>>k;
            for(int j=N-1;~j;j--){
                if(k&(1LL<<j)){
                    if(!base[j]) base[j]=k;
                    k^=base[j];
                }
            }
        }
    
        ll ans=0;
        for(int j=N-1;~j;j--){
            if((ans^base[j])>ans) ans=ans^base[j];
        }
    
        cout<<ans<<endl;
    
        return 0;
    }
    
  • 相关阅读:
    php中模拟多继承如何实现
    js进阶 12-4 jquery键盘事件如何使用
    php课程 3-12 带默认参数的函数怎么写
    android_线
    Cocos2d-x 文本渲染
    一张地图告诉你,只JavaScript不够!
    python 导入库问题
    Cocos2d-X字体
    R语言做文本挖掘 Part5情感分析
    Java存储区域——JVM札记&lt;一个&gt;
  • 原文地址:https://www.cnblogs.com/Tenshi/p/14410911.html
Copyright © 2011-2022 走看看