F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser  Logout 捐赠本站

2839: 集合计数

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 854  Solved: 470

Description

一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得
它们的交集的元素个数为K,求取法的方案数,答案模1000000007。(是质数喔~)

Input

一行两个整数N,K

Output

一行为答案。

Sample Input

3 2

Sample Output

6

HINT

【样例说明】

假设原集合为{A,B,C}

则满足条件的方案为:{AB,ABC},{AC,ABC},{BC,ABC},{AB},{AC},{BC}

【数据说明】

对于100%的数据,1≤N≤1000000;0≤K≤N;

Source

HOME
Back


 

答案就是交集至少为k - 至少为k+1......

我们先钦定k个元素,这是Cnk的。然后发现有2n-k个集合包含它,这些集合都可以选或不选,所以是22^(n-k)-1

然后我们发现还是有多算的,至少为j的元素多算了Cjk次,因为我们可以从这Cjk个方案中导出这一种。于是还要乘上这个系数。

那个2的连续阶乘,把上面的对phi(p)取模然后快速幂。

 #include <cstdio>

 const int MO = , phi = ;

 const int N = ;

 int f[N], pw[N], pww[N], fac[N], inv[N], invn[N];

 inline int C(int n, int m) {
if(n < m || n < || m < ) return ;
return 1ll * fac[n] * invn[m] % MO * invn[n - m] % MO;
} inline int qpow(int a, int b) {
int ans = ;
while(b) {
if(b & ) ans = 1ll * ans * a % MO;
a = 1ll * a * a % MO;
b = b >> ;
}
return ans;
} int main() { int n, k;
scanf("%d%d", &n, &k);
pww[] = pw[] = fac[] = inv[] = invn[] = ;
fac[] = inv[] = invn[] = ; pw[] = pww[] = ;
for(int i = ; i <= n; i++) {
fac[i] = 1ll * fac[i - ] * i % MO;
inv[i] = 1ll * inv[MO % i] * (MO - MO / i) % MO;
invn[i] = 1ll * invn[i - ] * inv[i] % MO;
pw[i] = pw[i - ] * % MO;
pww[i] = pww[i - ] * % (phi);
} int ans = ;
for(int i = k; i <= n; i++) {
int temp = 1ll * (qpow(, pww[n - i]) - ) * C(n, i) % MO * C(i, k) % MO;
if((i - k) & ) ans = (ans - temp) % MO;
else ans = (ans + temp) % MO;
}
printf("%d\n", (ans + MO) % MO);
return ;
}

AC代码

还可以用类似bzoj3622的方法,倒着逐步推出正确的结果。虽然会超时但是思想值得借鉴。

 #include <cstdio>

 const int MO = , phi = ;

 const int N = ;

 int f[N], pw[N], pww[N], fac[N], inv[N], invn[N];

 inline int C(int n, int m) {
if(n < m || n < || m < ) return ;
return 1ll * fac[n] * invn[m] % MO * invn[n - m] % MO;
} inline int qpow(int a, int b) {
int ans = ;
while(b) {
if(b & ) ans = 1ll * ans * a % MO;
a = 1ll * a * a % MO;
b = b >> ;
}
return ans;
} int main() { int n, k;
scanf("%d%d", &n, &k);
pww[] = pw[] = fac[] = inv[] = invn[] = ;
fac[] = inv[] = invn[] = ; pw[] = pww[] = ;
for(int i = ; i <= n; i++) {
fac[i] = 1ll * fac[i - ] * i % MO;
inv[i] = 1ll * inv[MO % i] * (MO - MO / i) % MO;
invn[i] = 1ll * invn[i - ] * inv[i] % MO;
pw[i] = pw[i - ] * % MO;
pww[i] = pww[i - ] * % (phi);
} int ans = ; /*for(int i = k; i <= n; i++) {
int temp = 1ll * (qpow(2, pww[n - i]) - 1) * C(n, i) % MO * C(i, k) % MO;
if((i - k) & 1) ans = (ans - temp) % MO;
else ans = (ans + temp) % MO;
}*/
for(int i = n; i >= k; i--) {
f[i] = 1ll * (qpow(, pww[n - i]) - ) * C(n, i) % MO;
for(int j = i + ; j <= n; j++) {
f[i] -= 1ll * f[j] * C(j, i) % MO;
if(f[i] < ) f[i] += MO;
}
} printf("%d\n", (f[k] + MO) % MO);
return ;
}

70分TLE代码

bzoj2839 集合计数的更多相关文章

  1. bzoj2839: 集合计数 容斥+组合

    2839: 集合计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 523  Solved: 287[Submit][Status][Discuss] ...

  2. bzoj2839 集合计数(容斥)

    2839: 集合计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 883  Solved: 490[Submit][Status][Discuss] ...

  3. bzoj2839 集合计数 组合计数 容斥原理|题解

    集合计数 题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007.(是 ...

  4. bzoj2839 集合计数(容斥+组合)

    集合计数 内存限制:128 MiB 时间限制:1000 ms 标准输入输出     题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 ...

  5. BZOJ2839:集合计数(容斥,组合数学)

    Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007. ...

  6. BZOJ2839 集合计数 容斥

    题目描述(权限题qwq) 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 它们的交集的元素个数为K,求取法的方案数,答案模100000000 ...

  7. BZOJ2839集合计数

    题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 它们的交集的元素个数为K,求取法的方案数,答案模1000000007.(是质数喔~ ...

  8. BZOJ2839 : 集合计数 (广义容斥定理)

    题目 一个有 \(N\) 个 元素的集合有 \(2^N\) 个不同子集(包含空集), 现在要在这 \(2^N\) 个集合中取出若干集合(至少一个), 使得它们的交集的元素个数为 \(K\) ,求取法的 ...

  9. 2019.02.09 bzoj2839: 集合计数(容斥原理)

    传送门 题意简述:对于一个有N个元素的集合在其2^N个子集中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数. 思路:考虑枚举相交的是哪kkk个,有CnkC_n^kCnk​种方案 ...

随机推荐

  1. PhpStorm 头部注释、类注释和函数注释的设置

    *设置位置:"Settings"->"file templates"; 如下图,设置头部注释.类注释以及函数注释,时间.用户名.文件名称等随机改变的属性, ...

  2. vue-axios的application/x-www-form-urlencod的post请求无法解析参数

    vue-axios的post会先将对象转为json然后再根据headers的设置再转一次格式,可以将参数先用qs.stringify()转一次再传输

  3. MySQL索引管理及执行计划

    一.索引介绍 二.explain详解 三.建立索引的原则(规范)

  4. EXAMPLE FOR PEEWEE 多姿势使用 PEEWEE

    使用 PEEWEE 断断续续的差不多已经三个年头了,但是没有像这次使用这么多的特性和功能,所以这次一并记录一下,需要注意的地方和一些使用细节,之后使用起来可能会更方便. 因为是使用的 SQLAched ...

  5. 在linux系统中实现各项监控的关键技术(1)--cpu使用率的计算

    转载自 Linux中通过/proc/stat等文件计算Cpu使用率 http://www.blogjava.net/fjzag/articles/317773.html proc文件系统 /proc文 ...

  6. /proc/diskstats

    读取磁盘统计信息,如下所示: linux-HpdBKE:~ # cat /proc/diskstats sda sda1 sda2 dm- dm- dm- sda为整个硬盘的统计信息,sda1为第一个 ...

  7. 一、PHP_OSS使用

    一.OSS PHP SDK下载 二.文件目录 三.参考手册快速入门对oss操作 以及到控制台找到相应参数并填写

  8. jaxp的dom方式操作(查找、添加、修改、删除、遍历节点)

    package cn.itcast.jaxptest; import java.io.IOException; import javax.xml.parsers.DocumentBuilder;imp ...

  9. do not track

    privacy.trackingprotection.enabled

  10. Vue数组更新及过滤排序

    前面的话 Vue为了增加列表渲染的功能,增加了一组观察数组的方法,而且可以显示一个数组的过滤或排序的副本.本文将详细介绍Vue数组更新及过滤排序 变异方法 Vue 包含一组观察数组的变异方法,它们将会 ...