题意简述:一个有n个元素的集合有
2n
个不同子集(包含空集),现在要在这
2n
个集合中取出若干集合(至少一个),使得它们的交集的元素个数为
K
,求取法的方案数,答案模1000000007。
题解:任意选
k
个最终交集,有
#include<bits/stdc++.h>
typedef long long ll;
const int N = 1e6 + 50;
const int P = 1000000007;
ll fac[N],inv[N],f[N];
ll ksm(ll x, int k){
ll ans = 1;
for (; k; k>>=1,x = x * x % P)
if (k & 1) ans = ans * x % P;
return ans;
}
void init(int n){
fac[0] = 1;
for (int i=1; i<=n; i++)
fac[i] = fac[i - 1] * i % P;
inv[n] = ksm(fac[n],P - 2);
for (int i=n-1; i>=0; i--)
inv[i] = inv[i + 1] * (i + 1) % P;
}
ll c(int n, int k){
return fac[n] * inv[k] % P * inv[n - k] % P;
}
ll solve(int n, int k){
f[n] = 2;
for (int i=n-1; i>=k; i--)
f[i] = f[i + 1] * f[i + 1] % P;
ll ans = 0;
for (int i=k,F=1; i<=n; i++,F*=-1)
ans = (ans + c(n-k,i-k) * (f[i] - 1) * F) % P;
return (ans * c(n,k) % P + P) % P;
}
int main(){
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
int n,k;
scanf("%d%d",&n,&k);
init(n);
printf("%lld\n",solve(n,k));
return 0;
}