bzoj 2839: Collection count

2839: Collection count

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 624  Solved: 346
[Submit][Status][Discuss]

Description

A set with N elements has 2^N different subsets (including the empty set), and now it is necessary to take several sets (at least one) from these 2^N sets, such that
The number of elements of their intersection is K, and the number of solutions to find the method, the answer modulo 1000000007. (It's a prime number~)

Input

A row of two integers N,K

Output

A line of answers.

Sample Input

3 2

Sample Output

6

HINT

 

[Example description]

Assuming the original set is {A,B,C}

, the scheme that satisfies the conditions is: {AB,ABC},{AC,ABC},{BC,ABC},{AB},{AC},{ BC}

【Data Description】

     For 100% data, 1≤N≤1000000; 0≤K≤N;

 

Source

 

 

    Binomial inversion template question hhhh

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000000,ha=1000000007;
int jc[maxn+5],ni[maxn+5],n,k,siz[maxn+5],T,ans,f[maxn+5];
inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
inline int ksm(int x,int y,const int M){ int an=1; for(;y;y>>=1,x=x*(ll)x%M) if(y&1) an=an*(ll)x%M; return an;}
inline int C(int x,int y){ return x<y?0:jc[x]*(ll)ni[y]%ha*(ll)ni[x-y]%ha;}
inline void init(){
    jc[0]=1; for(int i=1;i<=maxn;i++) jc[i]=jc[i-1]*(ll)i%ha;
    ni[maxn]=ksm(jc[maxn],ha-2,ha); for(int i=maxn;i;i--) ni[i-1]=ni[i]*(ll)i%ha;
}

inline void solve(){
	for(int i=k;i<=n;i++) f[i]=C(n,i)*(ll)ksm(2,ksm(2,n-i,ha-1),ha)%ha;
	for(int i=k;i<=n;i++)
	    if((i-k)&1) ans=add(ans,ha-C(i,k)*(ll)f[i]%ha);
	    else ans=add(ans,C(i,k)*(ll)f[i]%ha);
}

int main(){
	init(),scanf("%d%d",&n,&k);
	solve(),printf("%d\n",ans);
	return 0;
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324855566&siteId=291194637