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;
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; }