• LOJ#2127「HAOI2015」按位或


    用$ Min-Max$容斥之后要推的东西少了好多

    无耻的用实数快读抢了BZOJLuoguLOJ三个$ OJ$的Rank 1

    即将update:被STO TXC OTZ超了QAQ

    题意:集合$ [0,2^n)$中每次以一定给出概率产生一个数,求产生数按位或值为$ 2^n-1$的数字数量期望


    $ Solution:$

    根据$ Min-Max$容斥,令$ Max(S)$表示所有位中最后一次出现的时间,$Min(S)$表示第一次出现的时间

    显然有$ ans=Max(S)$

    根据$ Min-Max$容斥有

    $ Max(S)=sumlimits(-1)^{|T|+1}Min(T)$

    现在的问题是如何快速求出$ Min(S)$

    由于$ Min(S)$的意义是集合$ S$中第一次出现的位置的出现时间的期望

    有每次随机到集合$ S$中某一位的概率为:

    $ sumlimits_{T cap S eq emptyset}P_T$

    其中$ P_T$是产生$ T$这个数的概率

    因此可以得知

    $ Min(S)=frac{1}{sumlimits_{T cap S eq emptyset}P_T}$

    其中和原集有交可以转化成不属于原集的补集

    求原集的补集可以用$ FMT/FWT$优化,时间复杂度$ O(n·2^n)$


    $ my code:$

    #include<ctime>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define rt register int
    #define ll long long
    using namespace std;
    inline ll read(){
        ll x = 0; char zf = 1; char ch = getchar();
        while (ch != '-' && !isdigit(ch)) ch = getchar();
        if (ch == '-') zf = -1, ch = getchar();
        while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); return x * zf;
    }
    void write(ll y){if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}
    void writeln(const ll y){write(y);putchar('
    ');}
    int i,j,k,m,n,x,y,z,cnt,tot;
    double a[1048577];
    namespace fast_IO{
        const int IN_LEN=10000000,OUT_LEN=10000000;
        char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;
        inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}
        inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}
        inline void flush(){fwrite(obuf,1,oh-obuf,stdout);}
    }
    using namespace fast_IO;
    #define getchar() getchar_()
    double readf(){
        char ch=getchar();
        while(!isdigit(ch))ch=getchar();
        double value=ch-'0';
        ch=getchar();
        while(isdigit(ch)){
            value=value*10+ch-'0';
            ch=getchar();
        }
        if(ch=='.'){
            double cur=0.1;
            ch=getchar();
            while(isdigit(ch)){
                value+=cur*(ch-'0');
                cur*=0.1;
                ch=getchar();
            }
        }
        return value;
    }
    int main(){
        tot=read();n=1<<tot;
        for(rt i=0;i<n;i++)a[i]=readf();
        for(rt i=0;i<tot;i++)
        for(rt j=0;j<n;j++)if(j>>i&1)a[j]+=a[j^(1<<i)];
        double ans=0;
        for(rt i=0;i<tot;i++)if(a[n-1^(1<<i)]==1)return puts("INF"),0;
        for(rt i=0;i<n;i++)if(a[i]<1-0.0000001){
            if(__builtin_popcount(i)+tot&1)
            ans+=1.0/(1.0-a[i]);else ans-=1.0/(1.0-a[i]);
        }
        printf("%.10f",ans);
        return 0;
    }
  • 相关阅读:
    图片懒加载
    文字表情转换成小图标
    页面跳页面的参数获取
    vue v-for里面再套v-if和v-esle
    滚动条样式的修改
    vue-cil生产环境和发布环境的配置
    css隐藏滚动条并且可以滑动
    vue-cli脚手架一些插件安装elementui和axios
    闭包
    定时器、运动、日历
  • 原文地址:https://www.cnblogs.com/DreamlessDreams/p/10064025.html
Copyright © 2020-2023  润新知