列表

详情


NC19992. [HAOI2015]按位或

描述

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

输入描述

第一行输入n表示n个元素,第二行输入2^n个数,第i个数表示选到i-1的概率

输出描述

仅输出一个数表示答案,绝对误差或相对误差不超过1e-6即可算通过。如果无解则要输出INF

示例1

输入:

2
0.250.250.250.25

输出:

2.6666666667

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 324ms, 内存消耗: 8596K, 提交时间: 2020-11-12 23:48:10

#include<cstdio>
#include<cmath>
using namespace std;
const int N = (1 << 21) + 5;
double p[N];
inline void fwtor(int n, double f[], int inv = 1){
	int i, j, k;
	for(k = 1;k < n;k <<= 1)
		for(i = 0;i < n;i += k << 1)
			for(j = 0;j < k;j++)
				f[i + j + k] += inv * f[i + j];
}
int main(){
	int n, i;
	scanf("%d", &n);n = 1 << n;
	for(i = 0;i < n;i++)scanf("%lf", &p[i]);
	fwtor(n, p);
	for(i = n - 2, p[n - 1] = 0;i >= 0;i--){
		if(abs(p[i] - 1) < 1e-6)break;
		p[i] = 1 / (p[i] - 1);
	}if(i >= 0)printf("INF");
	else{
		fwtor(n, p, -1);
		printf("%.10lf", p[n - 1]);
	}
	return 0;
}

上一题