牛客练习赛76 E 牛牛数数 (线性基)
题目链接:https://ac.nowcoder.com/acm/contest/10845/E
线性基:https://oi.men.ci/linear-basis-notes/
二分后转化成线性基求第 \(k\) 大
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 101;
const int maxl = 62;
int T, n, m, q;
ll K;
int cnt;
struct LinearBasis{
ll a[maxn + 10];
int b[maxn];
LinearBasis(){
fill(a, a + maxn + 1, 0);
}
void insert(ll t){
for(int j = 62 ; j >= 0 ; --j){
if((t >> j) & 1){
if(a[j]){
t = t ^ a[j];
} else{
for(int k = 0 ; k < j ; ++k){
if((t >> k) & 1) t = t ^ a[k];
}
for(int k = j + 1 ; k <= 62 ; ++k){
if((a[k] >> j) & 1) a[k] = a[k] ^ t;
}
a[j] = t;
return;
}
}
}
}
}A;
bool check(ll k){
if(cnt != n) --k;
if(k > (1ll << cnt) - 1) return false;
else{
ll ans = 0;
for(int i = 0 ; i <= 62 ; ++i){
if((k >> i) & 1){
ans ^= A.a[A.b[i + 1]];
}
}
// printf("%lld\n", k, ans);
return ans <= K;
}
}
ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
int main(){
// freopen("data.in", "r", stdin);
// freopen("my.out", "w", stdout);
n = read(), K = read();
ll x;
for(int i = 1 ; i <= n ; ++i){
x = read();
A.insert(x);
}
cnt = 0;
for(int i = 0 ; i <= 62 ; ++i){
if(A.a[i]) A.b[++cnt] = i;
}
ll tot = 1ll << cnt;
if(cnt != n) ++tot;
ll l = 0, r = 1000000000000000000;
while(l < r){
ll mid = (l + r) >> 1;
if(check(mid)){
l = mid + 1;
} else{
r = mid;
}
}
// printf("%lld\n", r);
printf("%lld\n", tot - l);
return 0;
}