zoukankan      html  css  js  c++  java
  • [HAOI2015] 按位或

    初态下,分数为 (0)。每秒钟,随机选择一个 ([0,2^n-1]) 的数字与当前的数字做按位或运算。选择数字 (i) 的概率是 (p_i),求分数达到 (2^n-1) 的期望时间。(nleq 20)

    Solution

    先介绍一下 Min-Max 容斥原理。设 (max(S),min(S)) 分别是集合 (S) 中的最大值与最小值,则有

    [max(S)=sum_{Tsubseteq S} (-1)^{|T|+1} min(T) \ min(S)=sum_{Tsubseteq S} (-1)^{|T|+1} max(T) ]

    Min-Max 容斥原理对随机变量的期望成立。

    回到原问题,对于某个位置集合,考虑将每个位变为 (1) 的时间扔进一个集合,那么 (min(S)) 是集合中第一个变 (1) 元素的时间,(max(S)) 是最后一个。

    于是答案就是 (E(max(U))),其中 (U) 为全集。利用 Min-Max 容斥原理我们可以将它转化为求对于每一个子集的 (E(min(S))),而 (min(S)) 符合几何分布,于是有

    [egin{aligned} E(min(S)) &= sum_{i=1}^{infty} iP(min(S)=i) \ &= sum_{i=1}^infty i(sum_{TS=varnothing}p_T)^{i-1}(1-sum_{TS=varnothing}p_T) \ &= frac{1}{1-sum_{TS=varnothing}p_T} end{aligned} ]

    于是现在我们需要对所有 (Ssubseteq U),求出 (sum_{TS=varnothing} p_T)

    考虑 FMT,可以用来求出 (forall S, g(S)=sum_{Tsubseteq S} f(T))

    #include <bits/stdc++.h>
    using namespace std;
    
    double a[2000005],ans;
    int n;
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n;
        for(int i=0;i<1<<n;i++) cin>>a[i];
        int up=1<<n;
        for(int k=1;k<up;k<<=1)
            for(int s=0;s<up;s+=k<<1)
                for(int i=s;i<s+k;i++)
                {double a0=a[i];double a1=a[i+k];a[i]=a0;a[i+k]=a0+a1;}
        for(int i=1;i<up;i++) {
            if(1-a[(up-1)^i]<1e-10) {
                puts("INF");
                return 0;
            }
            ans += (__builtin_popcount(i)%2?1:-1)*1/(1-a[(up-1)^i]);
        }
        printf("%.8lf",ans);
    }
    
    
  • 相关阅读:
    易用网页下载器V0.1
    重复造轮之权限管理系统
    网页格式化排版代码,专用信息采集后的内容整理
    随机点名软件
    PHP导入Excel表格,读取Excel的内容到数组。
    汉字的书写效果的实现
    php的一个断点续传下载实现
    sentry的安装和使用以及各种问题处理
    CentOS下安装Redis及Redis的PHP扩展
    用ASP.NET_Regsql.exe创建Session数据库
  • 原文地址:https://www.cnblogs.com/mollnn/p/12397445.html
Copyright © 2011-2022 走看看