(筆者希望你在看這個之前學過了高斯消元)
我們先把線性基放到一邊,如何用高斯消元解決呢?
(下面的陳述可能有些問題,某些細節和實現希望讀者自己想一下)
---->從高到低確定每一位是否能選,即設這一位方程的右邊為1,解當前的方程組判斷是否有解,一共是解60次方程組\(o(n \cdot 60^3)\)
---->優化:保證消元時不將之前能異或得到的數重新列方程,這樣最多只有60個數,即\(o(60^4)\)
---->線性基基本上就是實現了這種優化,並將其廣泛應用了
\[\
\]\[\
\]線性基是乙個域內的一組基底,使得 (基底之間運算) 能和 (域內的所有數運算) 得到相同的集合
本文所提的線性基是基於 二進位制運算異或\(\oplus\)的
即構造一組基底\(d_i\)使得域內所有的數\(a_i\)通過異或得到的集合相同
\[\
\]\[\
\]動態擴大域插入
bool insert(ll x)\)之後,每乙個\(d_i\)都不存在了與後面\(d_j\)衝突的\(1\)
所以這其實也就是類似於高斯消元的思想
互相運算之後,這兩個基底是等價的
\(\text\)之後保證了每個\(d_i\)每個位上都不會有衝突並且滿足一一對應的性質,可以直接進行按位貪心了
\(\text\)之後,就無法再訪問原來的值了,所以對於需要持久化的情況慎用
1.最大異或和
又回到了引子
首先當然是預處理了線性基,但是我們這裡不用真的把高斯消元搬出來了
這時我們有兩種寫法
不\(\text\),貪心求解
ll ans=0;
drep(i,60,0) if((ans^d[i])>ans) ans^=d[i];
簡單粗暴
還可以\(\text\)之後直接按位貪心
rebuild();
ans=0;
drep(i,60,0) if(d[i]) ans^=d[i];
\[\
\]\[\
\]2.元素
題意:給定一些數及其權值,求最大獨立集的最大權值和
按權值排序,能取就取,貪心即可,這裡我們給出簡略證明策略正確性
假設保證權值遞減,若當前集合中已有的數為\(a,b,c,d,e\),現加入\(x\)與\(a,b\)產生衝突,即\(a \oplus \ b \oplus \ x=0\),這時取\(x\)一定不會更優
其實很顯然,因為如果取了\(x\),替換\(a,b\)中的乙個,此時仍能由異或產生\(a,b,x\)中的任意乙個,總體上獨立集的性質並未發生改變,但總權值減少了
證畢
int n;
ll d[n];
pair p[n];
bool ins(ll x)
int main()
\[\
\]\[\
\]3.第k小異或和
講這種應用之前我們先來細算不同異或和的個數:
設線性基元素的個數為cnt---->顯然就是\(2^\),即選或不選,且一定不會重複
這裡的第k小是不同的異或答案情況下
這裡我們先進行\(\text\), 保證不衝突
然後,對於每一位的數(從小到大列舉),如果這一位存在著\(d[i]\),那麼答案一定會是雙倍於之前
將\(k\)按照二進位制位分解後,對於每一位\(1\)取出答案異或即可
細節 :前面的定義裡已經講到,線性基的答案是異或不出\(0\)的,所以對於答案來說,如果存在\(0\)的情況,k要-1
(如何判斷0?插入時返回的值就是)
ll d[70],t[70],cnt;
bool ins(ll x)
void rebuild() \)
直接在找答案時保證該有的位有1,不該有的位沒有一就行了
ll work(ll k)
是不是很暴力。。。
其實這個複雜度可以再優化,但是筆者就不多講了
\[\
\]\[\
\]5.路徑最大異或和
注意這題問的是1-n的路徑
首先這題我們要想出乙個性質
任何一條路徑的異或值都可以隨意地與任意多個環相接!!!
(自己理解一下,很簡單)
所以就是處理出環值,插入線性基,對1-n路徑的異或值跑最大值就好了。。。
int n,m;
struct edgee[e<<1];
int head[n],ecnt;
void addedge(int u,int v,ll w);
head[u]=ecnt;
}#define erep(u,i) for(int i=head[u];i;i=e[i].nxt)
int from[e],to[e];
ll len[e];
ll dis[n];
int vis[n];
void dfs(int u)
}ll d[70];
bool ins(ll x)
6.xor-matic number of the graph-codeforces - 724g
直接看我的另一篇題解吧
----->傳送門
線性基學習筆記
線性基是幹嘛的呢?給定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...