【BZOJ4036】按位或(Min-Max容斥,FWT)
題面
題解
很明顯直接套用\(min-max\)容斥。
設\(E(max\{S\})\)表示\(S\)中最晚出現元素出現時間的期望,\(min\)同理。
那么\(E(max\{S\})=\sum_{T\subseteq S}(-1)^{|T|}E(min\{T\})\)
考慮怎么求\(E(min\{T\})\),很容易發現只需要或上了任何一位就行了。
也就是
\[E(min\{T\})=\frac{1}{\sum_{G\cap T\neq \phi }p[G]} \]
只需要任意一個和\(T\)存在交的集合\(G\)就會產生至少一個位。
現在的問題轉換成了怎么求任何一個和\(T\)有交的東西。
正難則反,求所有和\(T\)無交集的集合,設\(x=T\oplus(2^n-1)\),也就是\(T\)的補集。
顯然所有的與\(T\)無交集的集合都是\(x\)的子集,那么只需要預處理子集和就好了,\(FWT\)實現。
時間復雜度\(O(2^n n)\),代碼短的不行。
#include<cstdio>
int n,cnt[1<<20],N;
double P[1<<20],ans;
int main()
{
scanf("%d",&n);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 p=i<<1,j=0;j<N;j+=p)
for(int k=0;k<i;++k)
P[i+j+k]+=P[j+k];
for(int i=1;i<N;++i)if(1-P[(N-1)^i]>1e-8)ans+=((cnt[i]&1)?1:-1)/(1-P[(N-1)^i]);
if(ans<1e-10)puts("INF");else printf("%.10lf\n",ans);
return 0;
}