专栏文章

题解:P10596 BZOJ2839 集合计数

P10596题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqt0j7h
此快照首次捕获于
2025/12/04 10:15
3 个月前
此快照最后确认于
2025/12/04 10:15
3 个月前
查看原文
我们令 fkf_k 表示的交集的元素个数恰好kk,令 gkg_k 表示的交集的元素个数至少kk。根据二项式反演可得:
fk=i=kn(1)ik(ik)gif_k = \sum_{i=k}^{n}\left (-1 \right )^{i-k}\binom{i}{k}g_i
下面考虑如何求 gkg_k
我们先钦定其中的 kk 个元素为交集的元素,则方案数为 (nk)\binom{n}{k},这表示在选出的集合中这 kk 个元素一定选,这些钦定的集合还有 nkn-k 个元素可以选,枚举这 nkn-k 个元素选或不选共有 2nk2^{n-k} 种方案,由于不能不选,所以 gk=(nk)(22nk1)g_k = \binom{n}{k} ( 2^{2^{n-k}}-1)。最终答案为 fkf_k

参考代码

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 条评论,欢迎与作者交流。

正在加载评论...