1. 程式人生 > >線性基(一

線性基(一

兩個 nta pac 一個數 至少 運算 能夠 title 就是

1、線性基:

  若幹數的線性基是一組數a1,a2,...ana1,a2,...an,其中axax的最高位的11在第xx位。

  通過線性基中元素xorxor出的數的值域與原來的數xorxor出數的值域相同。

2、線性基的構造法:

  對每一個數pp從高位到低位掃,掃到第xx位為11時,若axax不存在,則ax=pax=p並結束此數的掃描,否則令p=pp=p xorxor axax。

3、查詢:

  用線性基求這組數xorxor出的最大值:從高往低掃axax,若異或上axax使答案變大,則異或。

4、判斷:

  用線性基求一個數能否被xorxor出:從高到低,對該數每個是

11的位置xx,將這個數異或上axax(註意異或後這個數為1的位置和原數就不一樣了),若最終變為00,則可被異或出。當然需要特判00(在構造過程中看是否有p變為0即可)。例子:(11111,10001)(11111,10001)的線性基是a5=11111a5=11111,a4=01110a4=01110,要判斷1111111111能否被xorxor出,1111111111 xorxor a5a5=0=0,則這個數後來就沒有是11的位置了,最終得到結果為00,說明1111111111能被xorxor出。

個人談一談對線性基的理解:

  很多情況下,只有有關異或運算和求最值,就可以用到線性基。線性基有很多很好的性質,比如說如果有很多個數,我們可以構出這些數的線性基,那麽這個線性基可以通過互相

xorxor,能夠構出原來的數可以相互xorxor構出的所有的數。所以可以大大減少判斷的時間和次數。同時線性基的任何一個非空子集都不會使得其xorxor和為0,證明也很簡單,反證法就可以說明。這個性質在很多題目中可以保證算法合法性,比如:BZOJ2460BZOJ2460。

  構造的方法有點像貪心,從大到小保證高位更大。也比較好理解。就是這幾行代碼:

  

1 2 3 4 5 6 7 8 9 10 11 12 13 for(int i=1;i<=n;i++) {     for(int j=62;j>=0;j--) {
     if(!(a[i]>>j)) continue;//對線性基的這一位沒有貢獻        if(!p[j]) { p[j]=a[i]; break; }//選入線性基中        a[i]^=p[j];      }    }

  

  可以把nn個數變成只有最大的數的二進制位數那麽多個數,這就是線性基的優秀之處。

  查詢的話,也是一個貪心思想,如果可以使得ansans更大,就把這一位的基xorxor進ansans。

   1 for(int i=62;i>=0;i--) if((ans^p[i])>ans) ans=ans^p[i];//從線性基中得到最大值

  這就是線性基的基本用法和個人的一些理解。

下面看一些練習(例題):

1、BZOJ2460

Description

相傳,在遠古時期,位於西方大陸的 Magic Land 上,人們已經掌握了用魔法礦石煉制法杖的技術。那時人們就認識到,一個法杖的法力取決於使用的礦石。
一般地,礦石越多則法力越強,但物極必反:有時,人們為了獲取更強的法力而使用了很多礦石,卻在煉制過程中發現魔法礦石全部消失了,從而無法煉制出法杖,這個現象被稱為“魔法抵消” 。特別地,如果在煉制過程中使用超過一塊同一種礦石,那麽一定會發生“魔法抵消”。
後來,隨著人們認知水平的提高,這個現象得到了很好的解釋。經過了大量的實驗後,著名法師 Dmitri 發現:如果給現在發現的每一種礦石進行合理的編號(編號為正整數,稱為該礦石的元素序號),那麽,一個礦石組合會產生“魔法抵消”當且僅當存在一個非空子集,那些礦石的元素序號按位異或起來為零。 (如果你不清楚什麽是異或,請參見下一頁的名詞解釋。 )例如,使用兩個同樣的礦石必將發生“魔法抵消”,因為這兩種礦石的元素序號相同,異或起來為零。
並且人們有了測定魔力的有效途徑,已經知道了:合成出來的法杖的魔力等於每一種礦石的法力之和。人們已經測定了現今發現的所有礦石的法力值,並且通過實驗推算出每一種礦石的元素序號。
現在,給定你以上的礦石信息,請你來計算一下當時可以煉制出的法杖最多有多大的魔力。

正解:貪心+線性基

解題報告:

  顯然這道題可以用線性基來維護一個我們選取的非空子集中不存在異或出00的情況,但是我們還需要得到的權值最大,那麽直接對於每件物品按權值排序,按權值從大到小插入到線性基中就可以保證得到的線性基中的元素是權值之和最大的。

2、BZOJ2115

Description

技術分享圖片

正解:線性基

解題報告:

  這道題要求從1到n的最大xor和路徑,存在重邊,允許經過重復點、重復邊。那麽 在圖上作圖嘗試之後就會發現,路徑一定是由許多的環和一條從1到n的路徑組成。容易發現,來回走是沒有任何意義的,因為來回走意味著抵消。考慮這道題求得是路徑xor和最大,所以必然我們要想辦法處理環的情況。我的做法是任意地先找出一條從1到n的路徑,把這條路徑上的xor和作為ans初值(先不管為什麽可行),然後我們的任務就變成了求若幹個環與這個ans初值所能組合成的xor最大值。顯然,我們需要預處理出圖上所有的環,並處理出所有環的環上xor值,這當然是dfs尋找,到n的路徑的時候順便求一下就可以了。

  當我們得到了若幹個環的xor值之後,因為是要求xor最大值,我們就可以構出這所有xor值的線性基。構出之後,再用ans在線性基上取max就可以了。

  現在我們來討論上述做法的可行性。

   第一種情況:我們對最終答案產生貢獻的某個環離1到n的主路徑很遠,這樣的話,因為至少可以保證1可以到達這個環,那麽我們可以走到這個環之後繞環一周之後原路返回,這樣從1走到環的路上這一段被重復經過所以無效,但是環上的xor值被我們得到了,所以我們並不關心這個環和主路徑的關系,我們只關心環的權值。

  第二種情況:我們任意選取的到n的路徑是否能保證最優性。假設存在一條更優的路徑從1到n,那麽這條路徑與我們原來的路徑構成了一個環,也就會被納入線性基中,也會被計算貢獻,假如這個環會被經過,那麽最後的情況相當於是走了兩遍原來選取的路徑,抵消之後走了一次這個最優路徑,所以我們無論選取的是哪條路徑作為ans初值,都可以通過與更優情況構成環,然後得到一樣的結果。這一證明可以拓展到路徑上的任意點的路徑選取。

  這樣我們就可以完美解決了。我第一次WA了一發,因為我沒有考慮到ans初值不為0,在線性基上取到xor的max的時候,不能單純以ans這一位是否為0來決定是否異或上基的這一位,必須要看異或之後取一個max做一個判斷才行。

3、codeforces724G

  直接鏈接到我的那篇博客過去辣

線性基(一