• bzoj 2839 集合计数


    转载请注明出处:

    http://www.cnblogs.com/hzoi-wangxh/p/7738616.html

    2839: 集合计数

    Time Limit: 10 Sec Memory Limit: 128 MB
    Submit: 500 Solved: 274
    [Submit][Status][Discuss]
    Description

    一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得
    它们的交集的元素个数为K,求取法的方案数,答案模1000000007。(是质数喔~)
    Input

    一行两个整数N,K
    Output

    一行为答案。
    Sample Input

    3 2
    Sample Output

    6
    HINT

    【样例说明】

    假设原集合为{A,B,C}

    则满足条件的方案为:{AB,ABC},{AC,ABC},{BC,ABC},{AB},{AC},{BC}

    N<=1000000,k<=N;

    题解:
    容斥原理。
    首先我们选出k个必须选的数Ckn,之后剩下的数共有22nk1 种选择方案。我们此次举出的是至少有k个交集的方案。
    之后运用容斥原理,斥掉k+1,容上k+2……
    公式为CknC0nk22nkCknC1nk22nk1+CknC2nk22nk2 ……
    对于22nk ,用降幂大法,先求出x=2nkmod(p1),再求2xmodp
    都乘Ckn,可以提出来最后乘。
    注意时刻取模。

    附上代码:

    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define int long long
    int jie[2001000],ny[2001000],mod=1000000007;
    int n,k,ans;
    int ksm(int,int,int);
    int getc(int,int);
    signed main()
    {
    //  freopen("in.txt","r",stdin);
        scanf("%lld%lld",&n,&k);
        int f=1;
        ny[0]=jie[0]=1;
        for(int i=1;i<=n;i++)
            jie[i]=jie[i-1]*i%mod;
        ny[n]=ksm(jie[n],mod-2,mod);
        for(int i=n-1;i>=1;i--)
            ny[i]=ny[i+1]*(i+1)%mod;
        for(int i=k;i<=n;i++)
        {
            int l=getc(n-k,i-k);
            int x1=ksm(2,n-i,mod-1);
            int x2=ksm(2,x1+mod-1,mod);
            ans=(ans+f*l*(x2-1)%mod+mod)%mod;
            f=-f;
        }
        ans*=getc(n,k);
        printf("%lld",ans%mod);
        return 0;
    }
    int ksm(int x,int y,int p)
    {
        int z=x,sum=1;
        while(y)
        {
            if((y&1)==1)
                sum=sum*z%p;
            y=y>>1;
            z=z*z%p;
        }
        return sum;
    }
    int getc(int x,int y)
    {
        return jie[x]*ny[y]%mod*ny[x-y]%mod;
    }
  • 相关阅读:
    Qt开发经验小技巧226230
    Qt编写物联网管理平台37逻辑设计
    关于Qt数据库开发的一些冷知识
    Golang多线程垂直输出字符串
    Python合并两个有序数组
    Python找字符串中的最长回文子串
    qemu
    面试_链表类
    Sword nlohmann::json的使用
    聊聊 RPA 方向的规划:简单有价值的事情长期坚持做
  • 原文地址:https://www.cnblogs.com/hzoi-wangxh/p/7738616.html
Copyright © 2020-2023  润新知