線性基學習筆記

2022-05-05 21:09:10 字數 1521 閱讀 2286

集合\(s\)有子集\(t\)

使得\(s\)的任意子集的元素的亦或和

都能被\(t\)的某個子集的元素亦或得到

且\(t\)的任何子集的亦或和不為\(0\)

\(t\)就是\(s\)的線性基

顯然\(s\)的子集亦或和的值域與\(t\)的子集亦或和的值域相等

比如說\(s=\\) (二進位制)

那麼\(t\)就是\(\\)

高斯消元

高斯消元可以看做求一組n階向量的線性基的過程

最後求出的矩陣的秩,就是線性基的元素個數

消完元後的線性無關組,就是一組線性基

求\(xor\)線性基與此類似,只是用乙個\(long long\)來代替高斯消元的\(n\)階向量

高斯消元最後保留的是乙個類似上三角矩陣的東西,

與此同理,

\(s=\\) (二進位制)

\(t=\\)

如上面的例子,最高位在0位上的只有1,在1位上的只有10,在2位上的只有100

具體求法:

依次將數插入到線性基,

如果該數的最高位1上對應的線性基元素為0,

那麼就將這個數作為該位的線性基元素,插入成功,退出

否則將這個數亦或該位上的線性基元素,

這時這個數的最高位1變小,就繼續往下找

直至該數插入成功

或者被亦或成了0,說明這個數可以被其他幾個數的亦或和表示出來,插入失敗

**

#define ll long long

ll p[maxn]; //最高位1在第i位上的線性基元素,如果沒有,就為0

inline void ins(ll x)

luogup3812

二、查詢某個數是否在亦或和的值域集合內

如果能成功插入這個數,就不在值域集合內,

否則就在值域集合內

inline bool check(ll x)

int t,n,m;

ll p[maxn];

bool flag;

inline void ins(ll x){ //插入乙個數x

for(int i=maxlog;i>=0;--i)

if(x&(1ll<=0;--i)

if(p[i])

for(int j=i-1;j>=0;--j)

if(p[i]>(p[i]^p[j]))

p[i]^=p[j];

int cnt=-1;

for(int i=0;i<=maxlog;++i)

if(p[i]) p[++cnt]=p[i]; //將不為0的p[i]排名

m=read();

while(m--){

x=read();

if(flag) --x; //0佔了乙個名次

if(x>=(1ll《以上只是線性基應用的幾個例子,只要明白了原理,我們可以用線性基解決很多問題

練習題彩燈

新nim遊戲

元素luogup4869

luogup4151

線性基學習筆記

線性基是幹嘛的呢?給定n個數,求所有數的異或和最大是多少?求解這類問題的時候,就需要線性基了 個人感覺線性基本身就一種貪心。首先定義ba se i bas e i 表示最高位1在i位的數是什麼 對於新進來的數tm p tmp 我們先找出他最高位上的1,假設為第 j j 位,然後看一下ba se j ...

線性基 學習筆記

includeusing namespace std using ll long long const int maxn 5e5 5 原來的數 const int maxbit 63 ll a maxn 原來的數 ll p maxbit p j 第j位為最高位1的數 最高位1在第j位的數 int m...

線性基 學習筆記

按位計算,如果相同記為0,不同記為1。如果,a b c,c b a 交換律結合律 對於任何數,x x 0,x 0 x 對 於一 段序列a n,異或 和為a1 a2 an 對於一段序列a n,異或和為a 1 a 2 a n 對於一段序列 an 異或和為 a1 a2 an 設t s,所有 這樣的子 集t...