[HAOI2015]按位或 min-max容斥+FWT

本文探讨了一个数学问题,即从数字0开始,通过随机选择并执行或操作,期望达到特定数值所需的时间。通过min-max容斥原理,文章提供了一种求解所有数出现一次的期望次数的方法,并给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description
刚开始你有一个数字000,每一秒钟你会随机选择一个[0,2n−1][0,2^n-1][0,2n1]的数字,与你手上的数字进行或操作。选择数字i的概率是p[i]p[i]p[i]。保证0&lt;=p[i]&lt;=10&lt;=p[i]&lt;=10<=p[i]<=1∑p[i]=1\sum p[i]=1p[i]=1问期望多少秒后,你手上的数字变成2n−12^n-12n1


Sample Input
2
0.25 0.25 0.25 0.25


Sample Output
2.6666666667


关于min−maxmin-maxminmax容斥的一点东西:
min−maxmin-maxminmax容斥的模型:给出n个数出现的概率,求所有数出现一次的期望次数。
设一个元素的大小为这个元素出现的时间。
min(S)min(S)min(S)为集合中最小的元素。
max(S)max(S)max(S)为集合中最大的元素。
PPP为概率,EEE为期望次数。
可知P(min(S))=∑i∈SPiP(min(S))=\sum_{i \in S}PiP(min(S))=iSPi
E(min(S))=1P(min(S))E(min(S))=\frac 1{P(min(S))}E(min(S))=P(min(S))1
对于模型,我们需要求解的实际上是E(max(S))E(max(S))E(max(S))
那么就有一个式子:
E(max(S))=∑T⊂SE(min(T))∗(−1)∣T∣+1E(max(S))=\sum_{T \subset S}E(min(T))*(-1)^{|T|+1}E(max(S))=TSE(min(T))(1)T+1

回到这道题,考虑求出E(min(S))E(min(S))E(min(S))
那么只要与SSS有交集其实对SSS就是有贡献的。
那么这个东西实际上不是很好求。
把他反过来就相当于求补集的子集,这个可以FWT解决。


#include <ctime>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

#define eps 1e-8
using namespace std;
typedef long long LL;
int _max(int x, int y) {return x > y ? x : y;}
int _min(int x, int y) {return x < y ? x : y;}
int read() {
	int s = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
	return s * f;
}

int n, cnt[1 << 20];
double ans, P[1 << 20];

int main() {
	int n = read(); int N = 1 << n;
	for(int i = 0; i < N; i++) scanf("%lf", &P[i]), cnt[i] = cnt[i >> 1] + (i & 1);
	for(int i = 1; i < N; i <<= 1) {
		for(int j = 0; j < N; j += i << 1) {
			for(int k = 0; k < i; k++) {
				P[j + k + i] += P[j + k];
			}
		}
	} ans = 0;
	for(int i = 0; i < N; i++) if(1.0 - P[i ^ (N - 1)] > eps) 
	ans += (cnt[i] & 1 ? 1 : -1) / (1.0 - P[i ^ (N - 1)]);
	if(ans < eps) puts("INF"); else printf("%.8lf\n", ans);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值