1. 程式人生 > >UOJ#36. 【清華集訓2014】瑪裏茍斯 線性基

UOJ#36. 【清華集訓2014】瑪裏茍斯 線性基

end pow 分類討論 概率 異或和 etc turn using +=

原文鏈接https://www.cnblogs.com/zhouzhendong/p/UOJ36.html

題解

按照 $k$ 分類討論:

k=1 : 我們考慮每一位的貢獻。若有至少一個數第 $i$ 位為 $1$ ,則對答案的貢獻為 $2^i/2$ 。

k=2 : 發現每個異或和的平方為 $\sum_i\sum_j2^{i+j}bit_ibit_j$。那麽考慮第 $i$ 位和第 $j$ 位的積的期望值。如果所有的數中,第 $i$ 位和第 $j$ 位均相等且非全零,那麽參考 k=1 的情況,期望為 1/2;否則,第 $i$ 位為 $1$ 的概率為 1/2,第 $j$ 位為 $1$ 的概率為 1/2,$i×j$ 為 $1$ 的概率為 0.25 。

$k\leq 3$ : 由於答案不超過 $2^{63}$ ,直接把線性基搞出來之後暴力枚舉就好了。

代碼

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
LL read(){
	LL x=0,f=0;
	char ch=getchar();
	while (!isdigit(ch))
		f|=ch==‘-‘,ch=getchar();
	while (isdigit(ch))
		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
const int N=100005;
int n,k;
ULL a[N];
void init(){
	static ULL x[64];
	clr(x);
	n=read(),k=read();
	for (int i=1;i<=n;i++){
		ULL v=read();
		for (int i=63;~i;i--)
			if (v>>i&1ULL)
				if (!x[i]){
					x[i]=v;
					break;
				}
				else
					v^=x[i];
	}
	n=0;
	for (int i=63;~i;i--)
		if (x[i])
			a[++n]=x[i];
}
void Out(ULL x){
	cout<<x/2;
	if (x&1LLU)
		cout<<".5";
}
namespace k1{
	void solve(){
		ULL ans=0;
		for (int i=1;i<=n;i++)
			ans|=a[i];
		Out(ans);
	}
}
namespace k2{
	void solve(){
		ULL ans=0;
		for (int i=0;i<33;i++)
			for (int j=0;j<33;j++){
				int f1=0,f2=0,f=0;
				for (int t=1;t<=n;t++){
					f1|=a[t]>>i&1ULL;
					f2|=a[t]>>j&1ULL;
					f|=(a[t]>>i&1ULL)!=(a[t]>>j&1ULL);
				}
				if (!f1||!f2)
					continue;
				ans+=1ULL<<(i+j-f);
			}
		Out(ans);
	}
}
namespace k3{
	__int128 tot;
	__int128 Pow(__int128 x,int y){
		__int128 ans=1;
		for (;y;y>>=1,x*=x)
			if (y&1)
				ans*=x;
		return ans;
	}
	void solve(){
		tot=0;
		for (int i=(1<<n)-1;i>=0;i--){
			ULL tmp=0;
			for (int j=0;j<n;j++)
				if (i>>j&1)
					tmp^=a[j+1];
			tot+=Pow(tmp,k);
		}
		while (tot%2==0&&n>1)
			n--,tot/=2;
		cout<<(ULL)tot/2;
		if (tot%2==1)
			cout<<".5";
	}
}
int main(){
	init();
	if (k==1)
		k1::solve();
	else if (k==2)
		k2::solve();
	else
		k3::solve();
	return 0;
}

  

UOJ#36. 【清華集訓2014】瑪裏茍斯 線性基