LOJ 114 k 大異或和

2022-05-09 15:59:01 字數 1530 閱讀 7139

[loj#114]k 大異或和

試題描述

這是一道模板題。

給由 n個數組成的乙個可重集 s,每次給定乙個數 k,求乙個集合 t⊆s,使得集合 t在 s的所有非空子集的不同的異或和中,其異或和 t1

xor t2

xor … xor t|

t| 是第 k小的。

輸入

第一行乙個數 n。

第二行 n個數,表示集合 s。

第三行乙個數 m,表示詢問次數。

第四行 m個數,表示每一次詢問的 k。

輸出

輸出 m行,對應每一次詢問的答案,第 k小的異或和。如果集合 s的所有非空子集中,不同的異或和數量不足 k,輸出 -1。

輸入示例

312

3512

345

輸出示例

012

3-1

資料規模及約定

1≤n,m≤10​5

​​,0≤s​i​​≤2​50​​

題解

對線性基進行高斯消元,離散後對 k 進行二進位制拆分。

#include #include #include #include #include #include using namespace std;

#define ll long long

const int buffersize = 1 << 16;

char buffer[buffersize], *head, *tail;

inline char getchar()

return *head++;

}ll read()

while(isdigit(c))

return x * f;

}#define maxn 55

int n, cnt;

ll bit[maxn], cb[maxn];

bool has0;

int main()

a ^= bit[j];

} if(!a) has0 = 1;

} for(int i = maxn - 1; i; i--)

for(int j = i - 1; j; j--) if(bit[i] >> j-1 & 1)

bit[i] ^= bit[j];

for(int i = 1; i < maxn; i++) if(bit[i]) cb[cnt++] = bit[i];

int q = read();

while(q--)

for(int i = cnt - 1; i >= 0; i--) if(k >> i & 1) ans ^= cb[i];

printf("%lld\n", ans); }

return 0;

}

LOJ114 k大異或和

傳送門 vjudge和hdu也有但是我覺得loj好看!而且限制少!不過本題描述有誤,應該是k小。首先我們需要對線性基進行改造。需要把每一位改造成為,包含最高位的能異或出來的最小的數。為啥呢?因為如果不滿足這個條件的話,那麼在之後的異或過程中,大的數反而會被小的數異或的更小。滿足了上述性質之後,我們就...

LOJ114 K大異或和 線性基

給出乙個n 1 e5 n leq1e5 n 1e 5的可重集合,求這個集合的第k kk小異或和。首先直接對n nn個數消元,然後把高位之後的1 11也盡可能消去,取出所有的非零的基向量。特判掉可能為0 00的情形 當且僅當非零基向量小於元素個數 剩下的t tt個基向量共有2t 12 1 2t 1 種...

LOJ 114 K大異或和 線性基

題目鏈結 需要注意如果線性基中表示的向量不足n個,說明一定存在一組向量滿足線性相關關係,即存在xor和為0的情況。這樣要使k減1。判斷是k 1 include include define gc getchar define maxin 100000 define gc ss tt tt ss in...