ZOJ3556 How Many Sets I【容斥原理】

来源:互联网 发布:mysql fetch object 编辑:程序博客网 时间:2024/05/20 11:19

题目链接:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3556


题目大意:

有一个集合S,S有N个元素,从S的子集中选k个集合,使得他们的交集为空。给你集合的元素

个数N和K,求满足情况的个数。


解题思路:

元素个数为N的集合S的子集共有2^N个,现在从子集中选出K个集合(可重复选)的有序组合,使

得他们的交集为空。

已知从子集中选K个有序组合总数为SUM = 2^(N*K)。

设F(x)为K个集合的有序组合个数(其中至少包含一个x)。

则F(x1 & x2)表示K个集合的有序组合个数(其中至少包含一个x1和一个x2)。

F(x1 & x2 & … & xk)表示K个集合的有序组合个数(其中至少包含一个x1、一个x2、…、一个xk)

而F(x) = 2^((N-1)*K),F(x1&x2) = 2^((N-2)*K),…,F(x1&x2&…&xk) = 2^((N-i)*K)。

根据容斥定理,最后得:ans = (2^K-1)^N。


AC代码:

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#define LL long long#define M 1000000007using namespace std;LL QuickMod(LL a,LL b, LL m){    LL ans = 1%m;    a %= m;    while(b > 0)    {        if(b & 1)            ans = ans*a%m;        a = a*a%m;        b >>= 1;    }    return ans;}int main(){    LL N,K;    while(~scanf("%lld %lld",&N,&K))    {        LL ans = (QuickMod(2, K, M) - 1 + M) % M;        ans = QuickMod(ans, N, M);        printf("%lld\n",ans);    }    return 0;}


0 0