# 【BZOJ2839】集合计数 【容斥原理】【二项式反演】

$\sum _{i=0}^{x}f\left(i\right){C}_{x}^{i}$

$g\left(x\right)=\left\{\begin{array}{ll}x=k& \text{1}\\ x\ne k& \text{0}\end{array}$

$g\left(x\right)=\sum _{i=0}^{x}f\left(i\right){C}_{x}^{i}$

$f\left(x\right)=\sum _{i=0}^{x}\left(-1{\right)}^{x-i}{C}_{x}^{i}g\left(x\right)$

$f\left(x\right)=\left\{\begin{array}{ll}0& \text{x

$ans$
$=\sum _{i=0}^{n}f\left(i\right)\alpha \left(i\right)$
$=\sum _{i=k}^{n}\left(-1{\right)}^{\left(i-k\right)}{C}_{i}^{k}{C}_{n}^{i}×\left({2}^{{2}^{n-i}}-1\right)$

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1000005,mod=1000000007;
int n,k,ans,jc[N],inv[N];
int fastpow(int a,int x){
int res=1;
while(x){
if(x&1){
res=1LL*res*a%mod;
}
x>>=1;
a=1LL*a*a%mod;
}
return res;
}
int C(int n,int m){
return 1LL*jc[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(){
scanf("%d%d",&n,&k);
jc[0]=1;
for(int i=1;i<=n;i++){
jc[i]=1LL*jc[i-1]*i%mod;
}
inv[n]=fastpow(jc[n],mod-2);
for(int i=n-1;i>=0;i--){
inv[i]=1LL*inv[i+1]*(i+1)%mod;
}
for(int i=n,base=2;i>=k;i--){
if((i-k)&1){
ans=(ans-1LL*C(i,k)*C(n,i)%mod*(base-1)%mod+mod)%mod;
}else{
ans=(ans+1LL*C(i,k)*C(n,i)%mod*(base-1))%mod;
}
base=1LL*base*base%mod;
}
printf("%d\n",ans);
return 0;
}
posted @ 2018-08-04 08:46  ez_2016gdgzoi471  阅读(111)  评论(0编辑  收藏  举报