1. 程式人生 > >線性基的一點理解

線性基的一點理解

1、線性基:

       若干數的線性基是一組數a1,a2,...an,其中ax的最高位的1在第x位。

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

2、線性基的構造法:

       對每一個數p從高位到低位掃,掃到第x位為1時,若ax不存在,則ax=p並結束此數的掃描,否則令p=p xor ax。

	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		for(int j=55;j>=0;j--)
		{
			if(!(a[i]>>j))continue;
			if(!p[j])
			{
				p[j]=a[i];
				break;
			}
			a[i]^=p[j];
		}
	}

3、查詢:

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

	for(int i=55;i>=0;i--)
		if((ans^p[i])>ans)ans=ans^p[i];

4、判斷:

       用線性基求一個數能否被xor出:從高到低,對該數每個是1的位置x,將這個數異或上ax(注意異或後這個數為1的位置和原數就不一樣了),若最終變為0,則可被異或出。當然需要特判0(在構造過程中看是否有p變為0即可)。例子:(11111,10001)的線性基是a5=11111,a4=01110,要判斷11111能否被xor出,11111 xor a5=0=0,則這個數後來就沒有是1的位置了,最終得到結果為0,說明11111能被xor出。

       很多情況下,只有有關異或運算和求最值,就可以用到線性基。線性基有很多很好的性質,比如說如果有很多個數,我們可以構出這些數的線性基,那麼這個線性基可以通過互相xorxor,能夠構出原來的數可以相互xorxor構出的所有的數。所以可以大大減少判斷的時間和次數。同時線性基的任何一個非空子集都不會使得其xorxor和為0,證明也很簡單,反證法就可以說明。這個性質在很多題目中可以保證演算法合法性。