#线性基#LOJ 114 k大异或和

题目


分析

建出线性基后,但是要求最小所以要重建线性基让大的尽量小,
然后第k小就是拼凑


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
typedef long long lll;
const int N=51; int n;
inline lll iut(){
	rr lll ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void print(lll ans){
	if (ans<0) putchar('-'),ans=-ans;
	if (ans>9) print(ans/10);
	putchar(ans%10+48); 
}
struct Vector_Space{
	lll re[N],p[N],tot;
	inline void BUILD(){
		memset(re,0,sizeof(re)),
		memset(p,0,sizeof(p)),tot=0;
	}
	inline void Insert(lll x){
		for (rr int i=N-1;~i;--i)
		if ((x>>i)&1){
			if (!re[i]) {re[i]=x; return;}
			x^=re[i];
		}
	}
	inline void Rebuild(){
		for (rr int i=1;i<N;++i){
			for (rr int j=i-1;~j;--j)
			if ((re[i]^re[j])<re[i])
			    re[i]^=re[j];
		}
		for (rr int i=0;i<N;++i)
		    if (re[i]) p[tot++]=re[i];
	}
	inline lll query(lll x){
		for (rr int i=tot-1;~i;--i)
		    if ((x^p[i])>x) x^=p[i];
		return x;
	}
	inline lll Kth(lll kth){
		if (tot^n) --kth;
		if (kth>=(1ll<<tot)) return -1;
		rr lll ans=0;
		for (rr int i=0;i<tot;++i)
		    if ((kth>>i)&1) ans^=p[i];
		return ans; 
	}
}H;
signed main(){
	n=iut(),H.BUILD();
	for (rr int i=1;i<=n;++i)
	    H.Insert(iut());
	H.Rebuild();
	for (rr int Q=iut();Q;--Q)
		print(H.Kth(iut())),putchar(10);
	return 0;
} 
posted @ 2020-11-05 09:55  lemondinosaur  阅读(64)  评论(0编辑  收藏  举报