BZOJ 4036 [HAOI 2015] 按位或

題面

剛開始你有一個數字00,每一秒鐘你會隨機選擇一個[0,2n1][0,2^n-1]的數字,與你手上的數字進行或操作。選擇數字ii的概率是p[i]p[i]。保證0p[i]10\le p[i]\le 1p[i]=1\sum p[i]=1問期望多少秒後,你手上的數字變成2n12^n-1

題解

論文題。在這裏插入圖片描述
在這裏插入圖片描述代碼很短。20行。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1<<20;
const double eps = 1e-8;
int n;
void FMT(double *f, int flg) {
	for(int i = 0; i < n; ++i)
		for(int s = 0; s < 1<<n; ++s)
			if(!(s>>i&1)) f[s|(1<<i)] += flg==1?f[s]:-f[s];
}
double p[MAXN], f[MAXN];
int main () {
	scanf("%d", &n);
	for(int s = 0; s < 1<<n; ++s) scanf("%lf", &p[s]);
	FMT(p, 1);
	for(int s = 0; s < 1<<n; ++s)
		if(fabs(p[s]-1) < eps) f[s] = 0;
		else f[s] = - 1.0 / (1 - p[s]);
	FMT(f, -1);
	double ans = f[(1<<n)-1];
	if(fabs(ans) < eps) puts("INF");
	else printf("%.10f\n", ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章