How Many Sets I(容斥定理)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3556
Give a set S, |S| = n, then how many ordered set group (S1, S2, ..., Sk) satisfies S1 ∩ S2 ∩ ... ∩ Sk = ∅. (Si is a subset of S, (1 <= i <= k))
Input
The input contains multiple cases, each case have 2 integers in one line represent n and k(1 <= k <= n <= 231-1), proceed to the end of the file.
Output
Output the total number mod 1000000007.
Sample Input
1 1 2 2
Sample Output
1 9
题解:输入n和k 分别表示有一个元素个数为n的集合,从中选出它的k个子集,求k个不相交子集的总数
题解:数学题,容斥定理
首先,n个元素的集合的子集有2^n个,每次从中选出k个集合就是总共2^nk种情况,其中包含一个公共元素的情况有C(1,n)*2^(n-1)k,包含两个公共元素的情况有C(2,n)*2^(n-2)*k,根据容斥定理得出总数为 所有情况-含有一个公共元素的+含有两个公共元素的-含有三个公共元素的+含有四个公共元素的……最后根据二项式公式,得出最后结果为(2^k-1)^n;
介绍一下容斥定理(加法公式):
引入:如果被计数的事物有A、B两类,那么,A类B类元素个数总和= 属于A类元素个数+ 属于B类元素个数—既是A类又是B类的元素个数。(A∪B = A+B - A∩B)
公式介绍:
对于这道题来说,要求的是拥有公共元素个数为0的,用容斥定理的推论上式的最后一项,移向即可,现在可以。
代码:
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int M = 1000000007; 5 #define ll long long 6 ll f(ll a,ll b) 7 { 8 ll res = 1; 9 while(b) 10 { 11 if(b&1) res = (res*a)%M; 12 a = a*a; 13 a %= M; 14 b= b/2; 15 } 16 return res%M; 17 } 18 int main() 19 { 20 ll n,k; 21 while(~scanf("%lld%lld",&n,&k)) 22 { 23 ll ans = f(2,k); 24 ans--; 25 ans = f(ans,n); 26 printf("%lld\n",ans); 27 } 28 return 0; 29 }