• 线性基入门


    推荐博客 : https://www.cnblogs.com/vb4896/p/6149022.html

          https://blog.csdn.net/qaq__qaq/article/details/53812883

    这个我觉得不是很好理解,花了一天半得时间,稍微懂了一点,写个博客

    首先我们要明确这个线性基可以解决什么样得问题,例如动态增加元素,求解集合异或最大值

    这里有一个增加操作,向里面增加一个元素,从最高位向下扫,当扫到 1 ,并且线性基中该位置为 0 ,则将这个元素加入到线性基中,否则用此元素去异或线性基中的数

    int val[maxn][40];
    void insert(int b[], int x){
        for(int i = 30; i >= 0; i--){
            if (x>>i&1){
                if (!b[i]) {b[i] = x; break;}
                else x ^= b[i];
            }
        }
    }
    

     合并

    void unit(int x,int y){
        // 将 x 暴力插入到 y 中 
        for(int i=30;i>=0;--i)
            if(val[x][i]) insert (val[y],val[x][i]);
    }
    

     查询

    查询一个元素是否再集合中x

    最大值

    从高位到低位去扫一遍

    int cal(int p){
        int ans = 0;
        for(int i = 30; i >= 0; i--){
            if ((ans^val[i]) > ans) {
                ans ^= val[i];
            }
        }
        return ans;
    }
    

     最小值

    int query(){
        for(int i = 0; i <= 30; i++){
            if (val[i]) return val[i];
        }
        return 0;
    }
    

     求解第K大

    将线性基重新构造一下

    ll cnt = 0;
    ll p[65];
    
    void rbuild(){
        for(ll i = 60; i >= 0; i--){ 
            for(ll j = i-1; j >= 0; j--){
                if ((1ll<<j)&a[i]) a[i] ^= a[j];
            }
        }
        
        for(ll i = 0; i <= 60; i++){
            if (a[i]) p[cnt++] = a[i];
        }
    }
    
    ll query(ll x){
        if (x >= (1ll<<cnt)) return -1;
        ll ans = 0;
        for(ll j = 60; j >= 0; j--){
            if ((1ll<<j)&x){
                ans ^= p[j];
            }
        }
        return ans;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    redis cluster 详解
    redis 数据占用内存大小分析
    java 中@RequestParam和@PathVariable
    git merge后,想恢复之前版本步骤
    Typescript中?? ?: ?. 都代表什么作用
    买卖股票的最佳时机系列问题
    最长递增子序列
    结构体统一说明
    Barcode Detection API All In One
    Learn Progressive Web Apps All In One
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/8964431.html
Copyright © 2020-2023  润新知