题目大意:给定n个元素,求交集大小为k的集合的集合共有多少种
考虑容斥原理 计算交集大小至少为i的集合有多少种
首先需要选出i个元素 方案为C(n,i)
其它2^(n-i)个集合每个可选可不选 一共2^[2^(n-i)]种
故答案为Σ[k<=i<=n]C(n,i)C(i,k)*2^[2^(n-i)]
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1001001 #define MOD 1000000007 using namespace std; int n,k; long long fac[M],inv[M],ans; void Linear_Shaker() { int i; fac[0]=1; for(i=1;i<=n;i++) fac[i]=fac[i-1]*i%MOD; inv[1]=1; for(i=2;i<=n;i++) inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD; inv[0]=1; for(i=1;i<=n;i++) (inv[i]*=inv[i-1])%=MOD; } long long C(long long n,long long m) { return fac[n] * inv[m] % MOD * inv[n-m] % MOD; } int main() { int i; cin>>n>>k; Linear_Shaker(); long long temp=2; for(i=n;i>=k;i--) { if(i!=n) (temp*=temp)%=MOD; ans+= (i-k&1?MOD-1:1) * C(n,i) % MOD * C(i,k) % MOD * temp % MOD; ans%=MOD; } cout<<ans<<endl; return 0; }
时间: 2024-10-06 15:16:24