若干數的線性基是一組數\(a_1,a_2,...a_n\)其中\(a_x\)的最高位的1在第x位。
通過線性基中元素\(xor\)出的數的值域與原來的數\(xor\)出數的值域相同。
對每乙個數\(p\)從高位到低位掃,掃到第\(x\)位為1時,若\(a_x\)不存在,則\(a_x=p\)並結束此數的掃瞄,否則令\(p=pxora_x\)。
用線性基求這組數\(xor\)出的最大值:從高往低掃\(a_x\),若異或上\(a_x\)使答案變大,則異或。
用線性基求乙個數能否被\(xor\)出:從高到低,對該數每個是1的位置x,將這個數異或上\(a_x\)(注意異或後這個數為1的位置和原數就不一樣了),若最終變為0,則可被異或出。當然需要特判0(在構造過程中看是否有p變為0即可)。
個人談一談對線性基的理解:
很多情況下,只有有關異或運算和求最值,就可以用到線性基。線性基有很多很好的性質,比如說
如果有很多個數,我們可以構出這些數的線性基,那麼這個線性基可以通過互相\(xor\),能夠構出原來的數可以相互\(xor\)x構出的所有的數。所以可以大大減少判斷的時間和次數。
同時線性基的任何乙個非空子集都不會使得其\(xor\)和為0,證明也很簡單,反證法就可以說明。
這個性質在很多題目中可以保證演算法合法性,比如:[bjwc2011]元素(按權值從大到小插入到線性基中就可以保證得到的線性基中的元素是權值之和最大的。)。
構造的方法有點像貪心,從大到小保證高位更大。也比較好理解。就是這幾行**:
for(re i=1;i<=n;++i)
for(re j=62;j>=0;--j)
if(a[i]&(1ll《可以把\(n\)個數變成只有最大的數的二進位制位數那麼多個數,這就是線性基的優秀之處。
查詢的話,也是乙個貪心思想,如果可以使得\(ans\)更大,就把這一位的基\(xor\)進\(ans\)。
for(int i=62;i>=0;i--) if((ans^p[i])>ans) ans=ans^p[i];
//從線性基中得到最大值
這就是線性基的基本用法和個人的一些理解。 模板 線性基
難度較大,請勿棄療 給定n個整數 數字可能重複 求在這些數中選取任意個,使得他們的異或和最大。n 50sample input33 21sample output 3看上去莫名其妙地想貪心。給些定義 s 為無符號整數集 即s n 記為 xor sum s x or s um s s1 s2 s s ...
模板 線性基
給定n個整數 數字可能重複 求在這些數中選取任意個,使得他們的異或和最大。線性基模板可解決 將n個整數看做集合a 線性基即為集合a的子集 線性基中每個元素的異或方案唯一,也就是說,線性基中不同的異或組合異或出的數都是不一樣的。線性基的二進位制最高位互不相同。這樣我們先構造出線性基 然後貪心的去搞最大...
線性基講解
1 線性基 若干數的線性基是一組數a1 a2,a na1,a2,an 其中axax 的最高位的11 在第xx位。通過線性基中元素xo rxor 出的數的值域與原來的數xo rxor 出數的值域相同。2 線性基的構造法 對每乙個數pp 從高位到低位掃,掃到第xx 位為11時,若ax ax不存在,則ax...