Set count (inclusion and exclusion)

Subject to the effect

     A set of N elements there are 2 ^ N different subsets (containing empty set), is now set to be taken out in a number of these sets of 2 ^ N (at least one), such that the number of elements to their intersection K, Acquire the number of programs, the answer mode 1,000,000,007.

answer

  First, the k selected is easy to think of as the intersection C from the n number of program elements (n, k)

  The following ideas are wrong, like biased ...... (-_-)!

    Then for each k nk optionally remaining elements in the elements, and together form a set of k, a total of 2 ^ (nk) species collection of sets, there are 2 ^ (2 ^ (nk)) such that in Scheme intersection is k

  Then ...... you will find there are different solutions there are a bunch of k repeat (inclusion and exclusion ah!) ...... I do not know how inclusion-exclusion

  Correct

  Selected from the remaining elements of nk elements, consisting of a collection of more then there is no intersection, making them the only intersection k

  Found that there are some wrong answers to the above scenario is the intersection of k + 1 elements, then subtract these two C (nk, 1) * 2 ^ (2 ^ (nk-1)), this will more than minus several times k + 2 is the intersection of the program, plus,

What came out of the inclusion-exclusion

  I.e., for each k, the intersection of k plus embodiment, subtracting k + 1 th intersection embodiment, with k + 2 th intersection embodiment, ...... plus (-1) ^ (nk) * ( the n intersection embodiment)

  Into a dry, enumeration intersection i, while not the empty set (i.e., not a not chosen), 2 ^ (2 ^ (ni)) To all without subtracting selected: ans + = (- 1) ^ (ik ) * C (n, i) * (2 ^ (2 ^ (ni)) - 1) * C (i, k);

  At first I code on the verge of TLE

  

  Then learn linear inversing hand, as follows:   

jc[0]=1;
for(int i=1;i<=n;i++) jc[i]=(long long)(jc[i-1]*i)%mod;
inv[n]=pow(jc[n],mod-2);
for(int i=n-1;i>=0;i--) inv[i]=((inv[i+1]%mod)*(i+1)%mod)%mod;
Linear inverse yuan

 

         

  After my continuously changing, and I finally found the secret to the AC 30

    ans+=(C(i,n)*((1ll*(pow(2,q[n-i])-1)*C(k,i)*1ll)%mod*ha*1ll))%mod; 我没写那个括号(玄学问题,我也不知道,有大佬知道的话,麻烦告诉一声,lockey在此%)

 

  AC Code

 

#include<iostream>
#include<cstdio>
using namespace std;
const long long mod=1000000007;
int n,k;
long long q[1100000],jc[1100000],inv[1100000];
long long ans=0;
long long pow(long long a,long long b){
    long long ans=1;
    a%=mod;
    while(b){
        if(b&1) ans=(long long)(ans*a)%mod;
        b>>=1;
        a=(long long)(a*a)%mod;
    }
    return ans% v;
}
long long C(long long m,long long n){
    if(!m||m==n) return 1;
    if(m>n) return 0;
    if(m<mod&&n<=mod)
        return ((long long)((long long)(jc[n]*inv[m])%mod)*inv[n-m])%mod;
    return ((long long)C(m%mod,n%mod)*C(m/mod,n/mod))%mod;
}
int main () {
    scanf("%d%d",&n,&k);
    jc[0]=1,q[0]=1;
    for(int i=1;i<=n;i++) jc[i]=(long long)(jc[i-1]*i)%mod;
    inv[n]=pow(jc[n],mod-2);
    for(int i=n-1;i>=0;i--) inv[i]=((inv[i+1]%mod)*(i+1)%mod)%mod;
    for(int i=1;i<=n;i++) q[i]=(q[i-1]*2)%(mod-1);
    long long ha=1;
    for(int i=k;i<=n;i++,ha=-ha){
        ans+=(C(i,n)*((1ll*(pow(2,q[n-i])-1)*C(k,i)*1ll)%mod*ha*1ll))%mod;
    }
    cout<<1ll*(1ll*(ans+mod)%mod+mod)%mod<<endl;
}
View Code

 

Guess you like

Origin www.cnblogs.com/heoitys/p/11126819.html