struct L_B {
LL d[65], p[65];
int cnt;
void init() {
memset(d, 0, sizeof(d));
memset(p, 0, sizeof(p));
cnt = 0;
} // 1e18以内的数都适用.
bool Insert(LL val) {
for (int i = 60 ; i >= 0 ; i --) {
if (val & (1ll << i)) {
if (!d[i]) {
d[i]=val;
break;
}
val^=d[i];
}
}
return val > 0;
// 可判断val是否存在于线性基当中.
}
LL query_max() {
LL res = 0;
for (int i = 60 ; i >= 0 ; i --) {
if ((res^d[i]) > res) res ^= d[i];
}
return res;
}
LL query_min() { // 应该预先判断能否是0的情况..QAQ
for (int i = 0 ; i <= 60 ; i ++) {
if (d[i]) return d[i];
}
return 0;
}
void rebuild() { // 用于求第k小值.需要先进行独立预处理
for (int i = 60 ; i >= 0 ; i --) {
for (int j = i-1 ; j >= 0 ; j --) {
if (d[i] & (1ll<<j)) d[i] ^= d[j];
}
}
for (int i = 0 ; i <= 60 ; i ++) {
if (d[i]) p[cnt++]=d[i];
}
}
LL kthquery(LL k) { // 注意判断原序列异或出0的情况, 此时应该将k -- 在进行后面的操作.
LL res = 0;
if (k >= (1ll << cnt)) return -1;
for (int i = 60 ; i >= 0 ; i --) {
if (k & (1LL<<i)) res ^= p[i];
}
return res;
}
void Merge(const L_B &b) { // 把b这个线性基插入到当前这个线性基中.
for (int i = 60 ; i >= 0 ; i --)
if (b.d[i]) Insert(b.d[i]);
}
}LB;