淺談線性基


前言

首先講一下線性基是什么東西,線性基是一個集合,你在原集合中找到一個子集,子集中的數xor起來一定能在線性基中找一個對應子集的xor和與其相等。
比如說,{x,y}和{x,x^y} 就滿足這么樣一個關系。

原理

我們把這個擴展一下,比如說我們現在有一個集合A,我新加進來一個數a,那么a與A中的數xor一下肯定是沒有問題的。

性質

定義一個數的M值為他二進制上第一個1出現的位置。

我們每往線性基中插入一個數,我們要讓這個數的M值與之前線性基中的每一個數的M值都不同。

插入

那么如何實現呢?

void insert(LL c){
	for (int i=51;i>=0;i--){
		if (c&bit[i]){
			if (!xxj[i]){
				xxj[i]=c;
				break;
			}
			c=c^xxj[i];
		}
	}
}

在這里,xxj[i]表示目前線性基中M值為i的這個數是多少。
那么當我們新插入一個數C
我們從大到小枚舉C的每一個二進制位,如果當前位置上為1,如果對應的xxj[i]沒有數,那么這個數就變成xxj[i],否則xor上xxj[i],通過我們前面的原理,這樣正確性是對的,而且這樣我們再掃后面的位置時,保證出現的1就是第一個出現的
例:
xxj[3]=101
xxj[2]=0
插入110
110-->11
所以插入xxj[2]的時候M值已經為2了(這個應該比較好想)

那么我們就完成了線性基的插入,基於二進制位,所以插入的復雜度是log的,而且通過這種插入方式,我們線性基的大小就是基於二進制的位數了,log個。

合並

合並兩個線性基只需要把一個線性基暴力插入另一個即可,復雜度:線性基大小*插入復雜度,$ log_2^2$

刪除

這種不加特技的線性基不支持刪除操作

取最大值

我們從最高位倒着掃下來,掃到第i位,如果當前的答案ans這一位上為1,那么我們xor上xxj[i]一定只會變小,而且這個影響無法消除,因為xxj[i+1..n]都不可能在那ans第i位上變為1,(根據xxj[i]的性質),同理,如果ans這一位上位0,那么xor上ans[i]一定會讓答案變大。
當然如果xxj[i]==0,那就沒有影響

LL query_max(){
	LL ret=0;
	for (int i=51;i>=0;i--){
		if ((xxj[i]^ret)>ret) ret=ret^xxj[i];
	}
	return ret;
}

取xor d的最大值

那么只需要把ret的初值賦為d就行了,原理也和上面的相同

取最小值

只需要找到最小的i,且xxj[i]不等於0就行了

取k小值

乍一看,一般的線性基好像不可做,
問題在哪兒?
1000001
0000001
同時選1和2比只選1要差,所以我們無法做

但是如果線性基長成這樣
1000000
0100000
0010000
0001000
0000100
那么就好做了,因為選取1和2一定比只選1要優。

所以我么需要對原來的線性基rebuild一下,使得它變成上面那樣的形式,當然
1000010
0100001
0000101
這種形式也是可以的,xxj[最后一位]上沒有數,所以同時選2和3也比只選2優,盡管最后一位上的1被消掉了
所以我們要使得若xxj[i]!=0,那么線性基里其他的數第i位上都為0,所以我們只需要拿xxj[i]去xor一下那些數就好了。
rebuild之后的線性基怎么做:把k轉成二進制,若k的第i位為1,那么將ans xor 上rebuild后第i大的xxj就行了。

void rebuild()
{
    for (int i=60;i>=0;i--)
        for (int j=i-1;j>=0;j--)
            if (d[i]&(1LL<<j))
                d[i]^=d[j];
    for (int i=0;i<=60;i++)
        if (d[i])
            p[cnt++]=d[i];
}
long long kthquery(long long k)
{
    int ret=0;
    if (k>=(1LL<<cnt))
        return -1;
    for (int i=60;i>=0;i--)
        if (k&(1LL<<i))
            ret^=p[i];
    return ret;
}

以上就是我對線性基的一些個人理解,希望能幫助大家學習,謝謝
同時在此感謝Yveh的博客給了很大幫助。
也感謝同學給予的幫助zhouyuheng2003


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM