albus就是要第一個出場

一、題目

點此看題

二、解法

首先考慮沒有重複(序列個數等於線性基個數)的情況,那麼問題就是求一個值的排名(跟求排名的值差不多)

如果有重複的情況呢?我們考慮一個值在線性基ii位被異或爲00,那我們就把這個值歸類到ii位,設有ww個多餘的值。如果一個位置被選取了,那麼選奇數個數的子集方案數2w2^w,否則可以選當前位沒有被選取,那麼選偶數也是2w2^w,總方案數就是2nm2^{n-m}mm是重複的個數。

代碼也就不難了,仿照求排名的值。

#include <cstdio>
#define int long long
const int jzm = 10086;
int read()
{	
	int x=0,flag=1;char c;
	while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
	while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*flag;
}
int n,m,k,ans,p[40];
void ins(int x)
{
	for(int i=30;i>=0;i--)
	{
		if(!(x>>i)) continue;
		if(!p[i]) {p[i]=x;break;}
		x^=p[i];
	}
	if(!x) m=m*2%jzm;
}
void work()
{
	for(int i=1;i<=30;i++)
		for(int j=0;j<i;j++)
			if(p[i]&(1<<j))
				p[i]^=p[j];
}
signed main()
{
	n=read();m=1;
	for(int i=1;i<=n;i++)
		ins(read());
	work();
	k=read();
	for(int i=0,t=1;i<=30;i++)
		if(p[i])
		{
			if((k>>i)&1) ans+=t;
			t<<=1;
		}
	printf("%lld\n",(ans*m+1)%jzm);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章