考虑容斥原理 计算交集大小至少为
i
的集合有多少种
首先需要选出
其它
2n−i
个集合每个可选可不选 一共
22n−i−1
种
故答案为
∑i=kn(−1)i−kCinCki(22n−i−1)
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e6+5;
const int P=1e9+7;
inline ll Pow(ll a,int b,int P=::P){
int res=1;
for (;b;b>>=1,a=1ll*a*a%P) if (b&1) res=1ll*res*a%P;
return res;
}
ll fac[N],inv[N];
inline void Pre(int n){
fac[0]=1; for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i%P;
inv[1]=1; for (int i=2;i<=n;i++) inv[i]=inv[P%i]*(P-P/i)%P;
inv[0]=1; for (int i=1;i<=n;i++) inv[i]=inv[i]*inv[i-1]%P;
}
inline ll C(int n,int m){
return fac[n]*inv[m]%P*inv[n-m]%P;
}
int main(){
ll Ans=0,tmp,n,K;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%lld%lld",&n,&K); Pre(n);
for (int i=K;i<=n;i++){
tmp=C(i,K)*C(n,i)%P*((Pow(2,Pow(2,n-i,P-1))+P-1)%P)%P;
if ((i-K)&1) Ans+=P-tmp;
else Ans+=tmp;
}
printf("%lld\n",Ans%P);
return 0;
}