• luogu P3175 [HAOI2015]按位或


    传送门

    如果每个位置上的数字的意义是这个位置被加进集合的最早时间,那么我们要求的就是集合中最大数的期望,使用Min-Max容斥,(E(max(S))=sum_{Tsubset S}(-1)^{|T|+1}E(min(T))),这里的(E(min(T)))是集合中加进数字的期望时间,根据题意,加进一个集合数字概率为(sum_{scap T eemptyset}P_s),对应的期望,也就是(E(min(T))=frac{1}{sum_{scap T eemptyset}P_s})

    但是(sum_{scap T eemptyset}P_s)不是很好求,可以转化成(1-sum_{scap T=emptyset}P_s),也就是(1-sum_{ssubset ∁_{S}T}P_s),高维前缀和即可

    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define db double
    
    using namespace std;
    const int N=(1<<20)+10;
    il int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int n,nn;
    db p[N],ans,h[N];
    
    int main()
    {
        n=rd();
        nn=(1<<n)-1;
        int ff=0;
        for(int i=0;i<=nn;++i)
        {
            scanf("%lf",&p[i]);
            if(p[i]>1e-8) ff|=i;
        }
        if(ff^nn) return puts("INF"),0;
        for(int i=1;i<=nn;i<<=1)
            for(int j=0;j<=nn;++j)
                if((j&i)==i) p[j]+=p[j^i];
        h[0]=1;
        for(int i=0;i<=nn;++i)
        {
            h[i]=-h[i^(i&(-i))];
            if(fabs(1-p[nn^i])>1e-8)ans+=h[i]*1/(1-p[nn^i]);
        }
        printf("%.8lf
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    java实现快速排序
    java实现简单回文算法
    HTML条件注释
    LeetCode 将有序数组转换为二叉搜索树
    LeetCode 有效的数独
    Leetcode 买卖股票的最佳时机 II
    模拟登陆163邮箱
    oracle 视图的相关操作
    oracle 约束类别
    软件测试用例知识点梳理
  • 原文地址:https://www.cnblogs.com/smyjr/p/10285329.html
Copyright © 2020-2023  润新知