[HAOI2015]按位或(FWT)
阿新 • • 發佈:2019-03-17
cnblogs 需要 ssi clu min 就是 owas tchar 位或
設\(P(x=a)=p\)
那麽取到\(a\)的期望為
\(E(x=a)=∑_{k=1}^{∞}k(1?p)^{k?1}p=p∑_{k=1}^{∞}k(1?p)^{k?1}\)
[Luogu3175] [BZOJ4036] [DarkBZOJ沒有spj]
原理-shadowice
本題題解
我們要求的,實際上是一個集合\(n\)個\(1\)中最晚出現的\(1\)的期望時間
顯然\(minmax\)容斥
\(E(max\{S\})=∑_{T?S}(?1)^{|T|+1}E(min\{T\})\)
那麽問題就轉化為了求每個集合中最早出現的\(1\)的期望時間
假如在\(k\)時刻出現,那麽前\(k?1\)時刻一定都是取的補集的子集,記\(T\)補集的所有子集概率和為\(P\)
\(E(min\{T\})=∑_{k=1}^{∞}kP(1?P)^{k?1}\)
是一個離散變量的幾何分布
那麽取到\(a\)的期望為
\(E(x=a)=∑_{k=1}^{∞}k(1?p)^{k?1}p=p∑_{k=1}^{∞}k(1?p)^{k?1}\)
記\(f(x)=1+2x+3x^2+4x^3+…\)
則\(xf(x)=x+2x^2+3x^3+4x^4+…\)
則\((1?x)f(x)=1+x+x^2+x^3+…\)
對於\(0<x<1,(1?x)f(x)\)是收斂的,可以取到
\((1?x)f(x)=\frac{1}{1?x}\)
\(f(x)=\frac{1}{(1?x)^2}\)
所以
\(E(x=a)=p\frac{1}{p^2}=\frac{1}{p}\)
非常棒
於是有
\(E(min{T})=\frac{1}{1?P}\)
我們只需要求出所有集合的子集概率和就好了
其實就是或運算的\(FWT\)
#include<cstdio> #include<cstring> using namespace std; typedef long long LL; const int INF=1e9+7; inline LL read(){ register LL x=0,f=1;register char c=getchar(); while(c<48||c>57){if(c=='-')f=-1;c=getchar();} while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar(); return f*x; } const int MAXN=1<<20; const double eps=1e-8; double f[MAXN],ans; int bit[MAXN],n,len; int main(){ n=read();len=1<<n; for(int i=0;i<len;i++) scanf("%lf",&f[i]); for(int i=2;i<=len;i<<=1){ for(int j=0,p=i>>1;j<len;j+=i) for(int k=j;k<j+p;k++) f[k+p]+=f[k];//這裏的特殊寫法有助於理解FWT,FFT系列操作 } for(int i=0;i<len;i++) bit[i]=bit[i>>1]+(i&1); for(int i=1;i<len;i++){ double tmp=(1-f[(len-1)^i]); if(tmp<eps){printf("INF\n");return 0;} if(bit[i]&1) ans+=1.0/tmp; else ans-=1.0/tmp; } printf("%.8lf\n",ans); }
[HAOI2015]按位或(FWT)