線性基是乙個數的集
合數的集合}
數的集合
,並且每個序列都擁有至少一
個線性基
至少乙個線性基}
至少乙個線性
基,取線性基中若干個數異或起來可以得到原序列中的任何乙個數。
1.原序列裡面的任意乙個數都可以由線性基裡面的一些數異或得到
2.線性基裡面的任意一些數異或起來都不能得到0
3.線性基裡面的數的個數唯一,並且在保持性質一的前提下,數的個數是最少的
4.裡面的數都是線性無關的
相當於把原集合壓縮 是極小的滿足線性基性質的集合,它的任何真子集都不可能是線性基;
1.首先我們看一下就是對於因為線性基是原集合的乙個子集那麼,對於原集合的每乙個數我們看一下這個數是否可以插入,不能插入的條件就是線性基可以表示他了
2.線性基就是把每一位求取出來
求解過程就類似高斯消元:
ll d[70]
;inline
bool
insert
(ll x)
}return
false
;}
還有一種比較完美的插入方法:
const
int maxl =60;
struct linearbasis
void
insert
(long
long t)
// 此時 t 的第 j 位為 0,繼續尋找其最高位上的 1
}// 如果沒有插入到任何乙個位置上,則表明 t 可以由 a 中若干個元素的異或和表示出,即 t 在 span(a) 中}}
;
合併實際就是把其中乙個線性基插入其他另乙個線性基裡面就叫可以了:
void
mergefrom
(const linearbasis &other)
static linearbasis merge
(const linearbasis &a,
const linearbasis &b)
1.求集合xor的最大值
完整的說,是如何求在乙個序列中,取若干個數,使得它們的異或和最大。
首先構造出這個序列的線性基,然後從線性基的最高位開始,假如當前的答案異或線性基的這個元素可以變得更大,那麼就異或它,答案的初值為 0。
ll ans()
2求集合疑惑的最小值
注意,這裡指的是用線性基內的元素能異或出的最小值。
顯然就是最小的 d[i] 了,因為最小的 d[i]無論異或誰都會變大。
如果是求整個序列能異或出的最小值而不是這個序列的線性基能異或出的最小值的話,要另外
看一看有
沒有元素
不能插入
線性基,
如果有,
那麼最小
值就是0
,否則依
然是最小
的d[i
]要另外看一看有沒有元素不能插入線性基,如果有,那麼最小值就是 0,否則依然是最小的d [ i ]}
要另外看一看
有沒有元
素不能插
入線性基
,如果有
,那麼最
小值就是
0,否則
依然是最
小的d[
i]。3.如何求第k小值
完整的說,應該是——從乙個序列中取任意個元素進行異或,求能異或出的所有數字中第k
kk小的那個。
線性基模板
struct linerbasis
void
rebuild()
}bool
insert
(ll x)
x^=p[i];}
return0;
}bool
find
(ll x)
return0;
} ll max_xor()
ll min_xor()
ll sum()
ll kth_small_num
(ll k)
if(k>
(1ll
<||k<0)
return-1
; ll res=0;
for(
int i=
0;i++i,k>>=1)
if(k&
1)res^
=p[i]
;return res;}}
;
線性基學習筆記
線性基是幹嘛的呢?給定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...