牛客练习赛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;
}
posted @ 2021-01-24 11:48  Tartarus_li  阅读(129)  评论(0编辑  收藏  举报