hdu3949 XOR 線性基 求第k大
阿新 • • 發佈:2018-12-15
線性基是蠻久之前給我講的
當時這個題沒調出來一直留在這裡
今天才把它填完
按照的理解線性基就是一個數集
其中的數異或出來能表示出所有加入過這個集合的所有數
我們只需要對於最高位為某一位的數
存一個下來就可以了
查詢最大值的時候直接貪心從高位往低位選就可以了…
對於這個題第大
我們先把線性基構造出來
再把其中有的位提出來 要判斷是否出現過
然後我們就對於這些存在的位
每次類似於平衡樹的查詢方法一樣
左子樹大了就找左子樹
小了就減去左子樹往右子樹找 反正是的
Codes
#include<bits/stdc++.h>
#define file(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
#define go(x, i) for(register int i = head[x]; i; i = nxt[i])
#define For(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)
#define FOR(i, a, b) for(register int i = (a) , i##_end_ = (b); i >= i##_end_; -- i)
#define debug(x) cout << #x << " = " << x << endl
#define mem(a, b) memset(a, b, sizeof(a))
#define cpy(a, b) memcpy(a, b, sizeof(a))
#define min(a, b) (a < b ? a : b)
#define max(a, b) (b < a ? a : b)
#define inf (0x3f3f3f3f)
#define INF ( 1e18)
#define pb push_back
#define mp make_pair
#define x first
#define y second
typedef unsigned long long ull;
typedef unsigned int uint;
typedef long long ll;
typedef std::pair<ll, int> PLI;
typedef std::pair<int, int> PII;
typedef long double ldb;
typedef double db;
namespace IO {
#define getc() ((S_ == T_) && (T_ = (S_ = Ch_) + fread(Ch_, 1, Buffsize, stdin), S_ == T_) ? 0 : *S_ ++)
#define putc(x) *nowps ++ = (x)
const uint Buffsize = 1 << 15, Output = 1 << 23;
static char Ch_[Buffsize], *S_ = Ch_, *T_ = Ch_;
static char Out[Output], *nowps = Out;
inline void flush(){fwrite(Out, 1, nowps - Out, stdout); nowps = Out;}
template<class T>inline void read(T &_) {
_ = 0; static char __; T ___ = 1;
for(__ = getc(); !isdigit(__); __ = getc()) if(__ == '-') ___ = -1;
for(; isdigit(__); __ = getc()) _ = (_ << 3) + (_ << 1) + (__ ^ 48);
_ *= ___;
}
template<class T>inline void write(T _, char __ = '\n') {
if(!_) putc('0');
if(_ < 0) putc('-'), _ = -_;
static uint sta[111], tp;
for(tp = 0; _; _ /= 10) sta[++ tp] = _ % 10;
for(; tp; putc(sta[tp --] ^ 48)); putc(__);
}
template<class T>inline bool chkmax(T &_, T __) {return _ < __ ? _ = __, 1 : 0;}
template<class T>inline bool chkmin(T &_, T __) {return _ > __ ? _ = __, 1 : 0;}
}
using namespace std;
using namespace IO;
const int N = 100;
ll n, q, flag, cnt;
ll b[N], B[N];
void Solve() {
ll x; flag = 1, cnt = 0; mem(b, 0);
for(read(n); n -- ; ) {
read(x);
FOR(j, 62, 0) if((1ll << j) & x) {
if(!b[j]) {b[j] = x; break;}
x ^= b[j]; if(!x) {flag = 0; break;}
}
}
FOR(i, 62, 0) FOR(j, i - 1, 0) if((1ll << j) & b[i]) b[i] ^= b[j];
For(i, 0, 62) if(b[i]) B[++ cnt] = b[i];
for(read(q); q -- ; ) {
ll ans = 0, fuck = 1, k; read(k);
if(k > (1ll << cnt) - flag) {puts("-1"); continue;}
if(k == 1 && !flag) {puts("0"); continue;}
FOR(i, cnt, 1) {
if(flag) {
if(k > (1ll << (i - 1)) - fuck) k -= (1ll << (i - 1)) - fuck, fuck = 0, ans ^= B[i];
}
else {
if(k > (1ll << (i - 1))) k -= 1ll << (i - 1), ans ^= B[i];
}
}
cout << ans << endl;
}
}
int main() {
#ifdef ylsakioi
file("3949");
#endif
int t; read(t);
For(i, 1, t) printf("Case #%d:\n", i), Solve();
return flush(), 0;
}