題解 kth異或和 魔改版線性基

2022-02-23 21:03:46 字數 1278 閱讀 9263

魔改版線性基解決此類問題。

聯絡線性空間的性質,我們直接可以構造出這樣的基:

\[100000

\\010000

\\000010

\\000001

\]使得每個基的最高位是唯一的,我們的目的是要能夠保證從上往下一直異或一直變大,所以不能使基出現這樣的情況:

\[100001

\\000001

\]

乙個不能從上往下一直異或一直變大的例子。

考慮如何構造\(kth\) 大(小),考慮這樣的性質,我們記\(a_i\)表示從下往上第\(i\)個基,顯然從\(0\)開始,如果我們異或了\(a_x\),那麼我們可以保證我們會比這個線性空間內\(2^\)個值都要大,直接考慮從上往下查詢,類似樹上倍增。

考慮無解的情況,顯然當我們發現\(k \ge 2^\)時就無解了。

然而我們有乙個問題,那就是我們預設\(0\)是可以被表示出來的,然而我們知道,當給定元素全部互為不相關時,這個時候就不存在乙個\(0\)會被表示出來了。那麼我們可以特判一下即可 。

好,那麼如何構造從上往下一直異或一直變大的基呢?魔改一下就好了。具體看**。

分析複雜度:我們把魔改操作的\(log^2\)看做常數吧...那就是\(o(nlogn)\)

當然你如果不承認魔改操作是常數,那就繼續魔改\(upd\)函式,也可以做到\(nlogn\)。具體就是加入的時候從小往大加。

下面的第\(k\)小,轉換為第\(k\)大用\(2^​\)減去即可。

#include using namespace std;

typedef long long ll;

template inline ccf qr(ccf ret)

namespace bs

inline ll size()

inline void set()

inline void upd(ll x) else

x ^= data[t];

}if(not x) }}

inline ll que(ll k)

}return ret;

}inline void clear()

inline void debug()

cout << endl;}};

inline void init()

}bs::base qaq;

int main()

HDU 3949 異或線性基

題目鏈結 題意 有n nn個數和q qq個詢問,每個詢問給出乙個正整數k kk,問這n nn個數異或組合出的所有數中第k kk小的是什麼數,若不存在則輸出 1 1 1。思路 首先構建出這n nn個數的異或線性基。假設非零線性基共有tot totto t個,從小到大排列後,對於第x xx個線性基,前1...

51Nod 1577 異或湊數(線性基)

description 從左到右一共 n 個數,數字下標從1到 n 編號。一共m 次詢問,每次詢問是否能從第 l 個到第 r個數中 包括第 l 個和第 r個數 選出一些數使得他們異或為 k 資料量比較大。輸入請用掛 int read 輸出請用pu tsinput 單組測試資料。第一行乙個整數n 05...

線性基(處理集合異或的強力工具)

看了好多篇關於線性基的部落格,只是說明了怎麼求線性基,但是大都沒有說明為什麼這樣求線性基。有乙個集合 s t的滿足下面條件的乙個最小子集a a的所有子集的異或和的值域與t的所有子集的異或和的值域相同,那麼a就是t的線性基。1 張成 s的所有子集,其異或和的所有可能的結果組成的集合,為s的張成,記作s...