zoukankan      html  css  js  c++  java
  • 【Learning】min-max容斥以及推广

    min-max容斥

    给定集合S,设max(S)S中的最大值,min(S)S中的最小值,则我们有一个式子:

    max(S)=TS(1)|T|1min(T)

    这个东西就叫做min-max容斥。
    怎么证明?
    我们考虑构造一个容斥系数f(x),使得
    max(S)=TSf(|T|)min(T)

    考虑第x+1大的元素会被统计到的贡献。
    则这个贡献为i=0xCxi×f(i+1)
    简单来说,就是枚举有哪些集合的最小值会为第x+1大的元素。

    [x==0]=i=0xCxi×f(i+1)

    二项式反演一下
    f(x+1)=i=0x(1)xiCxi[i==0]

    得到
    f(x+1)=(1)x

    因此
    f(x)=(1)x1

    综上,
    max(S)=TSf(|T|)min(T)=TS(1)|T|1min(T)

    证明完毕。
    下面我们来看几道例题。
    由于min-max容斥对于期望同样满足,所以可以很方便地解决一些概率和期望问题。

    hdu4336 Card Collector

    有n种卡片,每一秒都有Pi的概率获得一张第i种卡片,求每张卡片都至少有一张的期望时间。
    我们记max(S)S中最后获得的那种卡片第一次获得的期望时间,min(S)S中的第一个获得的那种卡片第一次获得的期望时间。
    仍然满足

    max(S)=TS(1)|T|1min(T)


    min(T)=1iTPi

    直接计算即可。
    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=25;
    const double eps=1e-7;
    double a[N],ans;
    int n;
    void dfs(int now,int tot,double sum){
        if(now>n){
            if(sum>eps){
                if(tot&1){
                    ans+=1/sum;
                }else{
                    ans-=1/sum;
                }
            }
            return;
        }
        dfs(now+1,tot,sum);
        dfs(now+1,tot+1,sum+a[now]);
    }
    int main(){
        while(~scanf("%d",&n)){
            for(int i=1;i<=n;i++){
                scanf("%lf",&a[i]);
            }
            ans=0;
            dfs(1,0,0);
            printf("%lf
    ",ans);
        }
        return 0;
    }

    bzoj4036 按位或

    我们记max(S)S中最后被或到的元素第一次被或到的期望时间,min(S)S中的第一个被或到的元素第一次被或到的期望时间。

    max(S)=TS(1)|T|1min(T)


    min(S)=1TSPT

    我们如果求出了min(s),就直接计算就好了。
    怎么求?
    TSPT=sumTS=PT=sumT(allS)=(allS)PT

    然后FWT计算即可。
    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=1050005;
    int n,all,tmp,cnt[N];
    double sum,res,ans,a[N];
    int main(){
        scanf("%d",&n);
        all=1<<n;
        for(int i=0;i<all;i++){
            cnt[i]=cnt[i>>1]+(i&1);
            scanf("%lf",&a[i]);
            sum+=a[i];
            if(fabs(a[i])>1e-6){
                tmp|=i;
            }
        }
        if(tmp!=all-1){
            puts("INF");
            return 0;
        }
        for(int i=1;i<all;i<<=1){
            for(register int j=0;j<all;j+=(i<<1)){
                for(register int k=j;k<j+i;k++){
                    a[k+i]+=a[k];
                }
            }
        }
        for(register int i=0;i<all;i++){
            res=sum-a[all-1-i];
            if(res>1e-6){
                res=1/res;
            }else{
                res=0;
            }
            if(cnt[i]&1){
                ans+=res;
            }else{
                ans-=res;
            }
        }
        printf("%.8lf
    ",ans);
        return 0;
    }

    推广 kth min-max容斥

    我们考虑构造一个容斥系数f(x),使得

    kthmax(S)=TSf(|T|)min(T)

    考虑第x+1大的元素会被统计到的贡献。
    这个贡献为i=0xCxi×f(i+1)

    [x==k1]=i=0xCxi×f(i+1)

    二项式反演一下
    f(x+1)=i=0x(1)xiCxi[i==k1]

    得到
    f(x+1)=(1)(x(k1))Cxk1

    因此
    f(x)=(1)xkCx1k1

    综上,
    kthmax(S)=TSf(|T|)min(T)=TS(1)|T|kC|T|1k1min(T)

    有一道例题,还没弄懂,不会做:重返现世
    这道题是ypl学长的神题QwQ

  • 相关阅读:
    已设定选项readonly请加!强制执行
    Linux下NVIDIA显卡驱动安装方法
    C#使用MiniDump导出内存快照MiniDumper
    一些陈旧的注册表垃圾清理脚本:注册表冗余数据清理.reg
    脚本精灵一些脚本
    本地安装SonarQube Community8.1社区版进行代码质量管控
    spring redistemplate中使用setHashValueSerializer的设置hash值序列化方法
    spring-core-5.0.6.RELEASE-sources.jar中java源代码不全
    lombok插件/slf4j中字符串格式化
    light4j/light-4j一个轻量级的低延时、高吞吐量、内存占用量小的API平台
  • 原文地址:https://www.cnblogs.com/2016gdgzoi471/p/9476844.html
Copyright © 2011-2022 走看看