P3175 [HAOI2015]按位或

P3175 [HAOI2015]按位或

题目大意:

刚开始你有一个数字 \(0\),每一秒钟你会随机选择一个 \([0,2^n-1]\) 的数字,与你手上的数字进行或(C++,C 的 |,pascal 的 or)操作。选择数字 \(i\) 的概率是 \(p_i\)。保证 \(0\leq p_i \leq 1\)\(\sum p_i=1\) 。问期望多少秒后,你手上的数字变成 \(2^n-1\)

仅输出一个数表示答案,绝对误差或相对误差不超过 \(10^{-6}\) 即可算通过。如果无解则要输出 INF

样例 #1

样例输入 #1

2
0.25 0.25 0.25 0.25

样例输出 #1

2.6666666667

\(n\leq 20\)

总结:一道比较经典的\(Min\_Max\)容斥题

我们设集合\(U\)为所有二进制位的全集

题目等价于求\(E(Max(U))\)

这个东西显然不是很好求,我们考虑求解\(E(Min(S))\)

\(E=\sum val \times p\)(期望=概率 \(\times\) 值)

我们考虑设\(P(S)\)表示选中集合\(S\)其中一个的概率,\(Q(S)\)表示选中\(S\)的补集的子集的概率

\(Min(S)=k\),那么就需要在前\(k-1\)次选\(S\)的补集的子集,在第\(k\)次不选\(S\)的补集的子集

\(E(Min(S))=\sum_{k=1}^{\infty} k \times Q(S)^{k-1}(1-Q(S))\)

\(Q(S)=x\)

\(E(Min(S))=(1-x)\sum_{k=1}^{\infty} k \times x^{k-1}\)

\(E(Min(S))=(1-x)(1 \times 1 + 2 \times x + 3 \times x^2...)\)

我们观察后面那个式子,形式是一个等差\(\times\)等比的数列

我们考虑对后面的式子求和

\(f(x)=1 \times 1 + 2 \times x + 3 \times x^2...\)

\(xf(x)=1 \times x + 2 \times x^2 + 3 \times x^3...\)

两式相减,\((1-x)f(x)=1+x+x^2+x^3+....=\frac{1}{1-x}\)

\(\therefore E(Min(S))=\frac{1}{1-Q(S)}\)

所以我们要求出\(E(Min(S))\),我们首先要求出\(Q(S)\)

不难发现,\(Q(S)=\sum_{T\in S} P(S)\)

时间复杂度为\(O(3^n)\),直接算显然会超时

观察求和的形式很像求子集,于是我们就用高位前缀和进行优化,可以优化到\(O(n \times 2^n)\)

代码:

#include<bits/stdc++.h>
#define ll long long
#define int long long
#define fr(i,j,k) for(register int i=j;i<=k;++i)
#define rf(i,j,k) for(register int i=j;i>=k;--i)
#define foredge(i,j) for(register int i=head[j];i;i=e[i].nxt)
#define randfind(l,r) (rand()%((r)-(l)+1)+(l))
#define pb push_back
#define Times printf("Time:%.3lf\n",clock()/CLOCKS_PER_SEC)
using namespace std;
inline int read(){
	int x=0;
	bool f=0;
	char c=getchar();
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return f?-x:x;
}
inline ll Read(){
	ll x=0;
	bool f=0;
	char c=getchar();
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return f?-x:x;
}
inline void write(int x){
    if(x<0){putchar('-');x=-x;}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
inline void writeln(int x){write(x); puts("");}
inline void writepl(int x){write(x); putchar(' ');}
inline void Write(ll x){
    if(x<0){putchar('-'); x=-x;}
    if(x>9)Write(x/10);
    putchar(x%10+'0');
}
inline void Writeln(ll x){Write(x); puts("");}
inline void Writepl(ll x){Write(x); putchar(' ');}
const int Maxn=(1<<20)+10,mod=998244353,inv2=499122177;
const double cor[2][2]={{1.0,0.0},{1.0,1.0}},
icor[2][2]={{1.0,0.0},{-1.0,1.0}},
cand[2][2]={{0,1},{1,1}};
int n;
double a[Maxn],b[Maxn],c[Maxn];
double aa[Maxn],bb[Maxn];
inline void fwt(double *f,int len,const double h[2][2]){
	for(register int k=2;k<=len;k*=2){
		for(register int i=0;i<len;i+=k){
			for(register int j=i;j<i+k/2;j++){
				double x,y;
				x=f[j];
				y=f[j+k/2];
//				cout<<x<<' '<<y<<endl;
				f[j]=(x*h[0][0]+y*h[0][1]);
				f[j+k/2]=(x*h[1][0]+y*h[1][1]);
//				fr(I,0,len-1) cout<<f[I]<<' ';
//				cout<<endl;
//				f[j]=((x*h[0][0]%mod+mod)%mod+(y*h[0][1]%mod+mod)%mod+mod)%mod;
//				f[j+k/2]=((x*h[1][0]%mod+mod)%mod+(y*h[1][1]%mod+mod)%mod+mod)%mod;
			}
		}
	}
	return;
}
int N;
inline void init(){
	cin>>n;
	N=(1<<n);
	fr(i,0,N-1) cin>>a[i];
//	fr(i,0,N-1) cout<<a[i]<<' ';
//	puts("");
}
int siz[Maxn];
inline void copy(){
	fr(i,0,N-1) aa[i]=a[i];
//	fr(i,0,N-1) cout<<aa[i]<<' ';
//     puts("");
}
inline void work1(const double c1[2][2],const double c2[2][2]){
	copy();
//	fr(i,0,N-1) cout<<aa[i]<<' ';
//     puts("");
	fwt(aa,N,c1);
//     fr(i,0,N-1) cout<<aa[i]<<' ';
//     puts("");
//	fwt(aa,N,c2);
//	fr(i,0,N-1) cout<<aa[i]<<' ';
//	puts("");
}
inline void work(){
	work1(cor,icor);
	double ans=0;
	fr(i,1,N-1){
		siz[i]=siz[i/2]+(i&1);
		double now;
		now=1-aa[i^(N-1)];
		if(now<(1e-8)) {
			puts("INF");
			return;
		}
		now=1.0/now;
		if(siz[i]&1) ans=ans+now;
		else ans=ans-now;
	}
	printf("%.8lf",ans);
}
signed main(){
//	freopen("input.in","r",stdin);
//	freopen("output.out","w",stdout);
	init();
	work();
    // printf("\nTIME:%.3lf",(double)clock()/CLOCKS_PER_SEC);
	return 0;
}
posted @ 2022-08-18 16:41  AntelopeWang  阅读(21)  评论(0)    收藏  举报