码迷,mamicode.com
首页 > 其他好文 > 详细

线性基总结(其实就是我的模板)

时间:2019-08-27 21:12:31      阅读:70      评论:0      收藏:0      [点我收藏+]

标签:sizeof   空间   pair   bre   准备工作   个数   div   build   oid   

想知道线性基直接看大佬的https://blog.sengxian.com/algorithms/linear-basis, 我就是弄下我常用的操作。

定义

学过线代里面的“基向量”,基向量说的就是一组可以表示整个空间的向量。比如在三维空间中一个基向量就是(1,0,0) (0,1,0) (0,0,1)。线性基的定义也类似,给你一个数组a[ ],它的线性基就是一组可以表示数组a中任意一个数的一个数组p[ ]。这个表示的意思就和前面的基向量表示的意思类似,是通过p中几个元素的异或得到a中的任意一个元素。

性质

1 原序列里面的任意一个数都可以由线性基里面的一些数异或得到
2 线性基里面的任意一些数异或起来都不能得到0
3 线性基里面的数的个数唯一,并且在保持性质一的前提下,数的个数是最少的

#include<bits/stdc++.h>
#define mp make_pair
#define met(a, b) memset(a, b, sizeof(a))
#define ll long long
using namespace std;
ll p[70], newp[70], cnt;

void getp(ll x){ //构建
    for(ll i = 63; i >= 0; i--){
        if(!(x>>i)) continue;
        if(!p[i]){
            p[i] = x;
            break;
        }
        x ^= p[i];
    }
}

ll getmax(){ //求异或最大值
    ll ans = 0;
    for(int i = 63; i >= 0; i--){
        if((ans ^ p[i]) > ans) ans ^= p[i];
    }
    return ans;
}

ll getmin(){ //求异或最小值
    for(int i = 0; i <= 63; i++){
        if(p[i]) return p[i];
    }
    return 0;
}

bool judge(ll x){ //判断x是不是数组a中的
    for(ll i = 63; i >= 0; i--){
        if(x>>i) x ^= p[i];
        if(!x) return 1;
    }
    return 0;
}

void rebuild(){ //求第k小的准备工作
    cnt = 0;
    for(ll i = 63; i >= 0; i --){
        for(ll j = i - 1; j >= 0; j --)
            if(p[i] & (1 << j)) p[i] ^= p[j];
    }
    for(ll i = 0; i <= 63; i ++){
        if(p[i]) newp[cnt++] = p[i];
    }
}

ll getans(ll k){ //求第k小
    if(k >= (1ll << cnt)) return -1;
    ll ret = 0;
    for(ll i = 63; i >= 0; i --){
        if(k & (1ll << i)) ret ^= newp[i];
    }
    return ret;
}


int main(){
    int n;  cin >> n;
    for(int i = 1; i <= n; i++){
        ll x; cin >> x;
        getp(x);
    }
    rebuild();
    int m; cin >> m;
    while(m--){
        ll k; cin >> k;
        if(n != cnt) k--;  //注意这个
        cout << getans(k) << endl;
    }
    return 0;
}

 

线性基总结(其实就是我的模板)

标签:sizeof   空间   pair   bre   准备工作   个数   div   build   oid   

原文地址:https://www.cnblogs.com/philo-zhou/p/11420670.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!