专栏文章
题解:P10596 BZOJ2839 集合计数
P10596题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqt0j7h
- 此快照首次捕获于
- 2025/12/04 10:15 3 个月前
- 此快照最后确认于
- 2025/12/04 10:15 3 个月前
我们令 表示的交集的元素个数恰好为 ,令 表示的交集的元素个数至少为 。根据二项式反演可得:
下面考虑如何求 。
我们先钦定其中的 个元素为交集的元素,则方案数为 ,这表示在选出的集合中这 个元素一定选,这些钦定的集合还有 个元素可以选,枚举这 个元素选或不选共有 种方案,由于不能不选,所以 。最终答案为 。
参考代码
CPP#include<bits/stdc++.h>
#define int long long
const int mod=1e9+7,N=1e6+5;
using namespace std;
int n,k,fac[N],inv[N];
int c(int a,int b){return fac[a]*inv[b]%mod*inv[a-b]%mod;}
int qpow(int a,int b,int p){
int res=1;
while(b){
if(b&1) res=res*a%p;
a=a*a%p;
b>>=1;
}
return res;
}
int f[N],g[N];
signed main(){
scanf("%lld%lld",&n,&k);
fac[0]=1;
for(int i = 1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
inv[n]=qpow(fac[n],mod-2,mod);
for(int i = n-1;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;
for(int i = 0;i<=n;i++)
f[i]=c(n,i)*(qpow(2,qpow(2,n-i,mod-1),mod)-1)%mod;
for(int i = k;i<=n;i++){
int x;
if((i-k)%2==1) x=-1;
else x=1;
int tmp=c(i,k)*f[i]%mod;
tmp*=x;
g[k]=(g[k]+tmp+mod)%mod;
}
printf("%lld",g[k]);
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...