题目链接

题目大意:

对于集合 \(\{1,2,\dots,n\}\) ,求它的子集族中,有多少个满足:

  • 任意两个子集互不相同;
  • \(1,2,\dots,n\) 都在其中至少出现了 \(2\) 次。

答案对 \(M\) 取模。

看到这种东西就要想到容斥。

设 \(F_i\) 表示至少有 \(i\) 个数字只出现了一次。

更具体的,就是 \(F_i\) 个数只出现一次,其他的数出现次数随便。

由容斥我们可以知道:

\[Ans = \sum_{i=0}^n(-1)^iF_i
\]

我们来考虑这时 \(n-i\) 个随便的部分构成的方案数。

首先,这 \(n - i\) 个数随便定是否只出现了一次,可以看出方案数是 \(2^{n-i}\) 。

然后对于每一个得出的情况,我们都可以选或不选,所以就是 \(2^{2^{n-i}}\) 。

再来看从 \(n\) 个数选出 \(i\) 个一定出现一次的方案数 \(C_n^i\) 很简单。

如果我们设 \(f_i\) 表示恰好有 \(i\) 个数只出现了一次,那么可以得到:

\[F_i=f_i\times2^{2^{n-i}}\times C_n^i
\]

现在着手考虑 \(f_i\) 是怎么得到的。

我们设 \(g_{i,j}\) 表示 \(i\) 个只出现一次的数放到 \(j\) 个集合的方案数。

  • 当此时第 \(j\) 个集合没有不合法的数,此时 \(i\) 只能填在此处 \(\rightarrow g_{i-1,j-1}\)
  • 意味着 \(j\) 个集合里面都有不合法的数字了,这样的话第 \(i\) 个不合法的数可以选择加入到 \(j\) 个集合中任意一个,也可以不加入任何集合。(因为不是强制的) \(\rightarrow (j+1)g_{i-1,j}\)

非常显然的 \(g_{i,j}\) 自然是这两种情况的和。

\[g_{i,j}=g_{i-1, j-1}+(j+1)g_{i-1,j}
\]

最后我们枚举有几个集合里有非法的元素就可以了。

注意:除了不合法的数字一个集合中还可以有其他的元素,及 \((2^{n-i})^j\)

\[f_i=\sum_{j=0}^ig_{i,j}\times (2^{n-i})^j\\
Ans = \sum_{i=0}^n(-1)^i\times\sum_{j=0}^ig_{i,j}\times (2^{n-i})^j\times2^{2^{n-i}}\times C_n^i
\]

呃呃呃,这个 \(Ans\) 的式子可能有一点点乱。。。

Code

#include <cstdio>
#include <iostream>
#include <algorithm> #define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout) #define Enter putchar('\n')
#define quad putchar(' ') #define int long long
const int N = 3005; int n, mod, fac[N], g[N][N], ans; inline int power(int a, int n, int mod);
inline int C(int n, int m); signed main(void) {
std::cin >> n >> mod;
fac[0] = 1;
for (int i = 1; i <= n; i++)
fac[i] = fac[i - 1] * i % mod;
for (int i = 0; i <= n; i++) {
g[i][0] = 1;
for (int j = 1; j <= i; j++)
g[i][j] = (g[i - 1][j - 1] + (j + 1) * g[i - 1][j] % mod) % mod;
}
for (int i = 0, lala; i <= n; i++) {
int two = power(2, n - i, mod - 1);
two = power(2, two, mod);
int num = power(2, n - i, mod), F = 0, mul = 1;
for (int j = 0; j <= i; j++) {
F = (F + g[i][j] * mul) % mod;
mul = mul * num % mod;
}
if (i % 2 == 1) lala = mod - C(n, i);
else lala = C(n, i);
ans = (ans + F * lala % mod * two % mod) % mod;
ans = (ans % mod + mod) % mod;
}
std::cout << ans << std::endl;
return 0;
} inline int power(int a, int n, int mod) {
int ret = 1;
while (n) {
if (n & 1) ret = ret * a % mod;
a = a * a % mod;
n /= 2;
}
return ret;
}
inline int C(int n, int m) {
if (n < m) return 0;
int ret = fac[n];
ret = ret * power(fac[m], mod - 2, mod) % mod;
ret = ret * power(fac[n - m], mod - 2, mod) % mod;
return ret;
}

最新文章

  1. RSA_SHA256数字签名
  2. Struts学习总结-02 类型转换
  3. 关于php中的spl_autoload_register
  4. Jfinal连接自助数据库的数据源
  5. hdu 1042 N!(高精度乘法 + 缩进)
  6. (转)[jQuery]使用jQuery.Validate进行客户端验证(初级篇)——不使用微软验证控件的理由
  7. 读取pdf文件 .选择了itextsharp 库
  8. HDU--3487 Play with Chain (Splay伸展树)
  9. super.getClass()与this.getClass()
  10. IQueryable和IEnumerable,IList的区别
  11. (转)POPTEST创始人李爱然:谢谢,帮助我的朋友!!!!
  12. 通过数据分析告诉你北京Python开发的现状
  13. H5项目常见问题及注意事项,视频全屏,定位,屏幕旋转和触摸,偏页面重构向 来源joacycode的github
  14. [洛谷P1438] 无聊的数列
  15. LabVIEW(九):程序结构中的分支结构和顺序结构
  16. PHP全路径无限分类导航LINK代码实现
  17. P1005 矩阵取数游戏 区间dp 高精度
  18. css3 二维码 添加 扫描特效
  19. what’s this?
  20. Ntfs 下的链接符号创建

热门文章

  1. 运行npm install命令的时候会发生什么?
  2. 新华三Gen10服务器ilo5中刷新bios固件
  3. npm install xxxx --legacy-peer-deps命令是什么?
  4. 面试必问的8个CSS响应式单位,你知道几个?
  5. 【计算机网络】Stanford CS144 Lab Assignments 学习笔记
  6. 2.1 安装Linux系统对硬件有什么要求?
  7. 3.yum学习笔记
  8. Linux下的计划任务—crontab
  9. PowerJob高级特效-容器部署完整教程
  10. 什么叫做 Docker