【ZOJ 3556 How Many Sets I】

题目链接题目

大概题意:有一个大集合S,里面有n(≤231-1)个元素,现在从中任意选出k(≤231-1)个子集组成一个有序集合对(S1,S2.....Sk),问其中有多少个集合对满足所有选出的子集的交集为空(S1 ∩ S2 .....Sk = Φ)

做法

先说句废话。

首先要注意的是题目说所有的子集的交集为空集,不代表某两个子集之间交集一定为空。甚至有可能任意两个子集之间交集都不为空,但是所有子集之间的交集为空。

我当时想到这一点之后,就开始用排除法。即用全部减去不符合要求的。然后开始了漫长的推公式。。。。。。

推半天推不出来,上网看题解。发现是恶心的容斥原理。。。

题解一

(容斥原理不懂的同学可以跳过这一部分)

首先方案总数为(2^n)^k

所有子集的交集至少含一个元素的方案C(n,1)*(2^(n-1))^k

所以答案就是(2^n)^k-C(n,1)*(2^(n-1))^k,哈哈,这题真简单,要什么容斥原理。。。。

错!!!!!!!!

我当时也是这么想的,结果发现——————

交集只含一个元素的方案被减掉了,但是交集只含两个元素的方案被减了两次!

于是我们加多一项,变成了

(2^n)^k-C(n,1)*(2^(n-1))^k+C(n,2)*(2^(n-2))^k

但是仔细再想想,不对,那交集只含三个元素的方案发生了什么。。。

事实上,交集只含三个元素的方案被减了C(3,1)次,又被加上了C(3,2)次,所以还要减去一次,即变成

(2^n)^k-C(n,1)*(2^(n-1))^k+C(n,2)*(2^(n-2))^k-C(n,3)*(2^(n-3))

然后。。。。

是的,你猜对了,最后这条式子会变成这样的庞然大物:

(2^n)^k-C(n,1)*(2^(n-1))^k+C(n,2)*(2^(n-2))^k-C(n,3)*(2^(n-3))....

+(-1)^t*C(n,t)*(2^(n-t))^k........+(-1)^n*C(n,n)*(2^(n-n))^k

再然后,把这条式看成是类似(a+b)^n展开式的形式,整合得到(2^k-1)^n

再然后套个快速幂取模就行了。。。

总结:这种方法还是很有启发性的,除了式子庞大,极费脑力,考试时绝对推不出来就是了。

题解二

在和albertxwz的交流中,我发现了思想的闪光。

下面无耻的抄袭下他的简洁思想:

对于大集合每一个元素x,每个子集Si要么包含它,要么不包含它。也就是两种可能。

所以元素x在所有子集中的情况可以统计出来:2^k

但是所有子集不能都包含元素x,否则就不符合条件了,所以还要减1:2^k-1

总共有n个元素,再加上一个乘幂:(2^k-1)^n

哈哈,这题真简单,要什么容斥原理。。。

代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <iostream>
 5 using namespace std;
 6
 7 const int modnum = 1000000007;
 8
 9 int n, m;
10
11 int pow_mod(long long a, int x)
12 {
13   long long ans = 1;
14   for (long long i = 1; i <= x; i <<= 1)
15   {
16       if (x & i) ans = ans * a % modnum;
17       a = a * a % modnum;
18   }
19   return ans;
20 }
21 void doing()
22 {
23   printf("%d\n", pow_mod(pow_mod(2, m) - 1, n));
24 }
25 int main()
26 {
27   while (scanf("%d%d", &n, &m) == 2) doing();
28   return 0;
29 }
时间: 2024-10-31 11:44:23

【ZOJ 3556 How Many Sets I】的相关文章

[容斥原理] zoj 3556 How Many Sets I

主题链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do? problemId=4535 How Many Sets I Time Limit: 2 Seconds      Memory Limit: 65536 KB Give a set S, |S| = n, then how many ordered set group (S1, S2, ..., Sk) satisfies S1 ∩ S2 ∩ ... ∩ Sk = ?. (Si is

ZOJ 3556 How Many Sets I 二项式+容斥

n个元素的子集有2^n个 求从这些子集选出k个组成有序集 并且有序集的交集为空的方案数 总数为2^n^k 减去不符合的 不符合的为交集存在1个共同元素 存在2个共同元素.... 2^n^k-C(n, 1)*2^(n-1)^k+C(n, 2)*2^(n-2)^k.... (2^k-1)^n #include <cstdio> #include <cstring> using namespace std; typedef long long LL; //返回a^p mod n 快速幂

【ZOJ】3380 Patchouli&#39;s Spell Cards

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3957 题意:m个位置,每个位置填1~n的数,求至少有L个位置的数一样的概率(1<=n,m,l<=100) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct inum { static const int N=205,

【ZOJ】3785 What day is that day? ——浅谈KMP应用之ACM竞赛中的暴力打表找规律

首先声明一下,这里的规律指的是循环,即找到最小循环周期.这么一说大家心里肯定有数了吧,“不就是next数组性质的应用嘛”. 先来看一道题 ZOJ 3785 What day is that day? Time Limit: 2 Seconds      Memory Limit: 65536 KB It's Saturday today, what day is it after 11 + 22 + 33 + ... + NN days? Input There are multiple tes

poj 2006 Litmus Test 【即zoj 2351:计算酸的PH】

公式:  pH = -log10 [H+]  PH值根据氢离子浓度求出 ,[这里的 [H+] 浓度是摩尔每升为单位的] Ka = [H+] [acid ions] / [acid]   平衡常数K等于分解的氢离子和酸根离子乘积与未分解的酸分子的比值 输入格式:   Ka :常数   ori :初始酸浓度    m :1摩酸分子完全溶解 分解出氢离子数    n :1摩酸分子完全溶解 分解出氢离子数[注意是完全溶解] [这题需要特别注意的是]指数形式是可以直接输入的.如用scanf 或者 prin

【ZOJ】3430 Detect the Virus

动态建树MLE.模仿别人的代码模板各种原因wa后,终于AC. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 515*70 8 #define NXTN 256 9 10 bool visit[515]; 11 char str[3005]; 12 unsigned

【OpenCV新手教程之十八】OpenCV仿射变换 &amp;amp; SURF特征点描写叙述合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/33320997 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 知乎:http://www.zhihu.com/people/mao-xing-yun 邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本号: 2.4.9 本篇文章中.我们一起探讨了OpenCV

【OpenCV入门教程之十八】OpenCV仿射变换 &amp; SURF特征点描述合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/33320997 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 知乎:http://www.zhihu.com/people/mao-xing-yun 邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本: 2.4.9 本篇文章中,我们一起探讨了OpenCV中

POJ2396&amp;ZOJ1994--Budget【有源汇上下界可行流】

链接:http://poj.org/problem?id=2396 题意:给一个n*m的矩阵,给出每行的总和以及每列的总和,再给出某些位置的最小或最大限制,问是否存在可能的矩阵,如果存在输出一种矩阵信息. 思路:这是一个有源汇的上下界可行流,对于这种题,从汇点连一条弧到源点,容量为INF,这不会影响流量平衡条件,并且此时原图转换为了无源汇的上下界可行流,剩下的做法和无源汇一样. 建图:原图源点src连向每个行顶点,容量为每行的和,每个列顶点连向汇点,容量为每个列顶点的和,行顶点和列顶点间也各有一