有這樣乙個問題——乙個長度為\(n\)的序列\(a_1-a_n\),\(q\)個詢問,每次詢問\(l,r\),選出\(\...a_\}\)中乙個子集使得子集內元素異或和最大/小。
第一次出現在hnoi模擬賽,當時的\(n,q\)只有大概\(3*10^4\)還是\(10^5\)的樣子。然後毫不猶豫的寫了個\(n\log^3n+q\log^2n\)的線性基st表過了。。。
第二次出現在noi模擬賽,資料範圍大到了\(10^6\)!!!因為上一次ioi金牌爺laofu踩了標算。。。然後發現自己上次沒聽懂,只會寫個兩個\(\log\)的分治。
第三次出現在noi.ac的noip lus模擬賽,然後發現自己還是沒聽懂。。。。。。
noiac41 最短路
是個巧(wu)妙(chi)的二合一,另一部分的思路來自洛谷p4151 [wc2011]最大xor和路徑
我們離線處理,對於右端點都在\(r\)的詢問區間一起考慮。我們已知\([1,r]\)的線性基每一行被插入的數在原序列中的位置(從\(r\)到\(l\)插入)。對於乙個詢問,我們取出線性基中所有被插入位置\(\ge l\)的行來更新答案。
那麼如何快速從\([1,r-1]\)的線性基變到\([1,r]\)呢?毫無疑問我們這時會先插入\(a_r\),設它插入到了第\(j\)行。那麼原來在第\(j\)行的數現在就不會留在這裡了,會\(xor\ a_r\)後繼續嘗試著插入下面的行。操作過程就是:把原來的數取出來,插入當前數,繼續把後面原來的數取出來。。。如是迴圈。
總的複雜度變成了\((n+q)k\),十分優秀。
#include#define rg register
#define r rg int
#define g if(++ip==iend)fread(ip=buf,1,n,stdin)
using namespace std;
const int n=3e5+9,m=6e5+9;
char buf[n],*iend=buf+n,*ip=iend-1;
int he[n],ne[m],to[m],w[m],s[n],a[n],b[n],l[n],lb[39],at[39];
bool vis[n];
inline int in()
return x;
}inline void chkmn(r&x,r y)
void dfs(r x)
int main()
for(i=1;i<=q;++i)
printf("%d\n",b[i]);
return 0;
}
51nod1496最小異或和 亂搞
description 乙個集合包含一組相互不同的數字。現在我們要去尋找乙個集合,他要滿足如下性質 對於所有 x x s 要滿足l x r 1 s k 設s中第i個元素是 si 那麼 f s s1 s2 s s 的值要盡可能小。sample input 8 15 3 sample output 1這...
hdu 3949 XOR 線性基 第k小異或和
給定 n 個數,對其每乙個子集計算異或和,求第 k 小的異或和。先求得線性基。同上題,轉化為求其線性基的子集的第k小異或和。記 n 個數的線性基為向量組 b 有b i p i 1,p 1 lt p 2 lt lt p t 記 k 的二進位制表示為向量 vec 則第 k 小異或和為 oplus i 1...
最大異或和 線性基模板
鏈結 給定n個整數 數字可能重複 求在這些數中選取任意個,使得他們的異或和最大。1 leq n leq 50,0 leq a i leq 2 異或和本來沒有單調性,但是從高到低遍歷線性基是單調的。考慮第 i 位時,如果當前答案 x 第 i 位為0,就將 x 異或上 a i 否則不做任何操作。顯然每次...