HAOI2015按位或-FWT、min-max容斥

link:https://www.luogu.com.cn/problem/P3175

刚开始你有一个数字 0,每一秒钟你会随机选择一个 [0,2n1] 的数字,与你手上的数字进行 操作。选择数字 i 的概率是 pi。保证 0pi1pi=1 。问期望多少秒后,你手上的数字变成 2n1
1n21


一开始是 0 要每位变成 1,对每个数位集合考虑,相当于求 maxS=T(1)|T|+1min(T) ,对 minT 则是说子集内有一个数变成 1 就行,反过来算都变不了 1 的概率= jTcpj,则这部分的期望次数是 minT=11jTcpj
jTc 等于在说 jTc=Tc ,就是OR卷积的形式:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define endl '\n'
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=21;
const double eps=1e-9;
int n,mx;
double f[1<<N];
int main(){
fastio;
cin>>n;mx=(1<<n);
rep(i,0,mx-1)cin>>f[i];
for(int x=2;x<=mx;x<<=1){
int k=x>>1;
for(int i=0;i<mx;i+=x)for(int j=0;j<k;j++)f[i+j+k]+=f[i+j];
}
double ans=0;
bool bad=false;
rep(S,1,mx-1){
int C=((mx-1)^S);
if(fabs(f[C]-1)<eps){
bad=true;
break;
}
if(__popcount(S)&1)ans+=1/(1-f[C]);
else ans-=1/(1-f[C]);
}
if(!bad)cout<<fixed<<setprecision(8)<<ans;
else cout<<"INF";
return 0;
}
posted @   yoshinow2001  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示