【BZOJ4036】按位或(min-max容斥,FWT)

题面

BZOJ
洛谷

题解

很明显直接套用 minmax m i n − m a x 容斥。
E(max{S}) E ( m a x { S } ) 表示 S S 中最晚出现元素出现时间的期望,min同理。
那么 E(max{S})=TS(1)|T|E(min{T}) E ( m a x { S } ) = ∑ T ⊆ S ( − 1 ) | T | E ( m i n { T } )
考虑怎么求 E(min{T}) E ( m i n { T } ) ,很容易发现只需要或上了任何一位就行了。
也就是

E(min{T})=1GTϕp[G] E ( m i n { T } ) = 1 ∑ G ∩ T ≠ ϕ p [ G ]

只需要任意一个和 T T 存在交的集合G就会产生至少一个位。
现在的问题转换成了怎么求任何一个和 T T 有交的东西。
正难则反,求所有和T无交集的集合,设 x=T(2n1) x = T ⊕ ( 2 n − 1 ) ,也就是 T T 的补集。
显然所有的与T无交集的集合都是 x x 的子集,那么只需要预处理子集和就好了,FWT实现。
时间复杂度 O(2nn) 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值