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. C# Note21: 扩展方法(Extension Method)及其应用

    前言 今天在开会时提到的一个概念,入职3个多月多注重在项目中使用C#的编程知识,一直没有很认真地过一遍C#的全部语法,当我们新人被问及是否了解Extension Method时,一时之间竟不能很通俗准 ...

  2. UTF-8编码与GBK编码下的字符长度

    源码: package lsh.java.charset; import java.nio.charset.Charset; public class LengthOfUTF_8 { public s ...

  3. 压测工具使用(vegeta)

    一.压测工具vegeta 1.介绍 Vegeta 是一个用 Go 语言编写的多功能的 HTTP 负载测试工具,它提供了命令行工具和一个开发库. 官方地址:https://github.com/tsen ...

  4. 百度云虚拟主机配置 Thinkphp5.1

    材料 服务器:百度云虚拟主机(nginx+php7.0+linux) Thinkphp 5.1 问题 百度云默认目录为/webroot,但是我们的需求是将项目存放到/webroot/public下面. ...

  5. Play framework框架中通过post方式发送请求

    搞了好久这个最终还是在play官方文档中看见的发送请求的方式,国内好像很少有使用这个框架的,加之自己不是太愿意宣传,好东西总归是好东西,不说废话了. 在play中发送请求有两种常用的方式,一种get, ...

  6. Nginx GoAccess安装与配置

    1.下载并安装Geoip $ wget https://github.com/maxmind/geoip-api-c/releases/download/v1.6.12/GeoIP-1.6.12.ta ...

  7. a标签实现锚点功能

    a标签实现锚点功能 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  8. Civil 3D 二次开发 创建Civil 3D 对象—— 01 —— 创建几何空间点

    这一小节,我们创建派生于CivilCreateEntityDemo的类CivilCreateCogoPoint,来创建几何空间点. 1 创建类并添加字段及方法 首先在项目资源管理器中向本项目中添加类, ...

  9. Dirichlet's Theorem on Arithmetic Progressions POJ - 3006 线性欧拉筛

    题意 给出a d n    给出数列 a,a+d,a+2d,a+3d......a+kd 问第n个数是几 保证答案不溢出 直接线性筛模拟即可 #include<cstdio> #inclu ...

  10. xml 模块

    XML ———可扩展的标记语言 也是一种通用的数据格式 之所以用它 也是因为跨平台 XML 的语法格式: 1,任何的起始标签都必须有一个结束标签. <> 起始标签 </>结束标 ...