• [HAOI2015]按位或


    I.[HAOI2015]按位或

    在本题中,(minmathbb S) 表示 (mathbb S) 中第一个被取到的位置被取到的时间,(maxmathbb S) 表示最后一个被取到的位置被取到的时间。则我们要求的就是 ( ext E(maxmathbb S))

    现在,考虑计算 ( ext E(minmathbb T))

    (P(mathbb S)) 表示选一个数,是 (mathbb S) 子集的概率。显然,这个东西可以通过FMT简单求出。

    则,(minmathbb T=i) 的概率就是

    [P(mathbb{Ssetminus T})^{i-1}Big(1-P(mathbb{Ssetminus T})Big) ]

    这里的 (setminus) 符号是集合删除符号。因为 (mathbb T) 中只要取到一个就算成功,所以前 (i-1) 次都必须在 (mathbb T) 的补集里取,而最后一次不能在 (mathbb T) 的补集里取。为了简便,我们此处设 (p=P(mathbb{Ssetminus T}))。则要求

    [sumlimits_{i=1}ip^{i-1}(1-p) ]

    将其转换为

    [(1-p)sumlimits_{i=1}ip^{i-1} ]

    其是等差数列与等比数列之积的形式。故我们设 (A=sumlimits_{i=1}ip^{i-1}),则 (pA=sumlimits_{i=1}ip^i=sumlimits_{i=2}(i-1)p^{i-1}=sumlimits_{i=1}(i-1)p^{i-1})。计算 (A-pA),得到 (sumlimits_{i=1}p^{i-1}),其等于 (dfrac{1}{1-p})。故 ((1-p)A=dfrac{1}{1-p}),即 (A=dfrac{1}{(1-p)^2})。再乘上最外面的 (1-p),得到公式

    [ ext E(minmathbb T)=dfrac1{1-P(mathbb{Ssetminus T})} ]

    直接容斥即可。时间复杂度 (O(n2^n)),瓶颈在于FMT。

    代码为了图方便,直接枚举了 (mathbb{Ssetminus T})

    #include<bits/stdc++.h>
    using namespace std;
    const double eps=1e-10;
    int n,m;
    double f[1<<20],res;
    int main(){
    	scanf("%d",&n),m=1<<n;
    	for(int i=0;i<m;i++)scanf("%lf",&f[i]);
    	for(int i=0;i<n;i++)for(int j=0;j<m;j++)if(j&(1<<i))f[j]+=f[j^(1<<i)];
    	for(int i=0;i<m-1;i++){
    		if(f[i]+eps>1){puts("INF");return 0;}
    		if(__builtin_popcount((m-1)^i)&1)res+=1/(1-f[i]);else res-=1/(1-f[i]);
    	}
    	printf("%.10lf
    ",res);
    	return 0;
    }
    

  • 相关阅读:
    Android相对布局中控件的常用属性【转】
    Android:仿微信设置菜单
    Android:scrollview与listview共存
    感想12.26
    (C#)GDI+绘制垂直文字
    10.14 近期小结
    学习C++的忠告
    C# TCP学习笔记
    C#读书笔记(4)—重学数组
    近期学习计划 12.23
  • 原文地址:https://www.cnblogs.com/Troverld/p/14636918.html
Copyright © 2020-2023  润新知