線性基(處理集合異或的強力工具)

2021-08-18 11:23:32 字數 2503 閱讀 4117

看了好多篇關於線性基的部落格,只是說明了怎麼求線性基,但是大都沒有說明為什麼這樣求線性基。

有乙個集合 s  = ,t的滿足下面條件的乙個最小子集a =

a的所有子集的異或和的值域與t的所有子集的異或和的值域相同,那麼a就是t的線性基。

1、張成:s的所有子集,其異或和的所有可能的結果組成的集合,為s的張成,記作span(s)。

2、線性相關:對於乙個集合s,如果存在乙個元素sj,去除這個元素後得到的集合s'的張成span(s')中包含sj,即sj∈span(s'),則稱集合s是線性相關的。如果不存在這樣的sj,那麼集合s就是線性無關的。

3、線性基:有了上面兩個名詞,我們還可以這樣定義線性基。

(1)a ⊆ span(s)

(2)a是線性無關的

則集合a是集合s的線性基。

1、a是乙個集合的線性基,那麼它的任何真子集都不可能是線性基;

2、s中所有的向量都可以按唯一的方式表達為 a 中元素的線性組合(也就是異或和)。

我們令集合中的數為a1,a2,....,an,b[ ]陣列用來儲存線性基裡面的數。(下面的二進位制的位數下標從0開始)

**如下:

void create()

初始矩陣: 

0 0 0 

0 0 0

0 0 0

插入7之後:

1 1 1

0 0 0 

0 0 0 

插入3之後,為了維護對角矩陣,把7的低位消掉:

1 0 0

0 1 1 

0 0 0

插入1之後,把1上面的行的低位都消掉:

1 0 0 

0 1 0

0 0 1

然後就發現後面那幾個數都已經包含在b陣列的張成裡了,加不進去了。

上述過程是把線性基維護成乙個對角矩陣,其實我們還有一種**量比較少的線性基的構造方法,就是只把矩陣消成上三角矩陣,這樣的話同樣可以知道哪一位存在於線性基內。

我們把線性基封裝成乙個結構體,這樣使用起來方便一點:

struct linebasis

}

這裡的b陣列就是用於存線性基里的數,這個cnt是記錄線性基裡面有多少個數。

那麼這個cnt有什麼作用呢,2的cnt次冪就是這個線性基所有子集異或和能構成的不同元素的個數(這裡包括零)。

max_b是最大那個數二進位制的長度

下面介紹他的各個函式:

1、插入

上面雖然展示了一種線性基的構造方法,那個方法可以提現出線性基的性質,但是下面我們用它比較方便的寫法:

bool insert(ll val)

2、合併:

把乙個線性基里的元素乙個乙個的insert到另乙個裡面,就完成了合併。

linebasis merge(linebasis n1,linebasis n2)

1、求一組數所有組合能構成的不同異或和的個數:

求出這組數的線性基,線性基里數的個數為cnt,答案就為2的cnt次冪

hihocoder1723 子樹統計

2、存在性:

查詢x是否存在於異或集合中,跟上面構造方法的思想相似,從高位到低位掃瞄x位1的二進位制位,掃到第i位時,x ^= b[i],如果最後x變為0,則存在,否則不存在。

3、最大值:

求異或集合中的最大值

如果消成對角矩陣的話,直接把線性基中的所有元素異或起來即可。但是對於上三角矩陣,異或之前判斷一下是否能變大。

還可以求乙個數x與集合中某些數異或的最大值,只用把初值設為x就行了,單純求最大值時最初始值設為0.

ll querymax(ll x)

4、最小值:

最小值就是最低位上的線性基。

ll querymin()

5、k小值

這時候用構造出的上三角矩陣就不能解決這個問題了,我們要把上三角矩陣變換成對角矩陣,然後再把不為零的都按順序拿出來。這時候矩陣已經變成對角矩陣(至少是行最簡形矩陣),我們異或上某一行的值,答案就會變大一點。我們可以想象,從乙個陣列 a = 中選出幾個,求能組成第k小的值是多少,利用二進位制的性質,如果k的二進位制第i位為1,我們就加上陣列裡第i大的數。這裡的異或上乙個值也會變大一點,所以可以用同樣的思想。具體看下面**

void rebuild()

bool insert(ll val)

linebasis merge(linebasis n1,linebasis n2)

ll querymax(ll x)

ll querymin()

void rebuild()

{for(int i=max_b;i>=0;i--)

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

if(b[i]&(1ll<=(1ll<=0;i--)

if(k&(1ll<

如有錯誤,歡迎指出。

HDU 3949 異或線性基

題目鏈結 題意 有n nn個數和q qq個詢問,每個詢問給出乙個正整數k kk,問這n nn個數異或組合出的所有數中第k kk小的是什麼數,若不存在則輸出 1 1 1。思路 首先構建出這n nn個數的異或線性基。假設非零線性基共有tot totto t個,從小到大排列後,對於第x xx個線性基,前1...

51Nod 1577 異或湊數(線性基)

description 從左到右一共 n 個數,數字下標從1到 n 編號。一共m 次詢問,每次詢問是否能從第 l 個到第 r個數中 包括第 l 個和第 r個數 選出一些數使得他們異或為 k 資料量比較大。輸入請用掛 int read 輸出請用pu tsinput 單組測試資料。第一行乙個整數n 05...

題解 kth異或和 魔改版線性基

魔改版線性基解決此類問題。聯絡線性空間的性質,我們直接可以構造出這樣的基 100000 010000 000010 000001 使得每個基的最高位是唯一的,我們的目的是要能夠保證從上往下一直異或一直變大,所以不能使基出現這樣的情況 100001 000001 乙個不能從上往下一直異或一直變大的例子...