集合计数

题目描述

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

输入格式

一行两个整数N,K

输出格式

一行为答案。

样例

样例输入

3 2

样例输出

6

数据范围与提示

样例说明

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

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

数据说明

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

题解

看到这个题我们很自然的想到答案是

$\binom{n}{k}*f(n-k)$

其中f(i)表示i个元素的2i个集合中,选出任意多集合使交集为空的方案数,但是一个集合都不选是不合法的

一个暴力算法

显然f(0)=1

设g(i,j)表示从i个元素的集合中,选出任意多集合使交集为k个的方案数

$g(i,j)=\binom{i}{j}*f(i-j)$

对于i>1    $f(i)=2^{2^i}-1-\sum\limits_{j=1}^{i}g(i,j)$

注意不能一个集合都不选,但可以选择集合中没有任何元素的集合来组成一个对集合的集合,这涉及到-1的位置

复杂度O(n2)  期望得分70

正解 容斥原理

$f(n)=\sum\limits_{i=0}^{n}*(-1)^i*\binom{n}{i}*(2^{2^{n-i}}-1)$

集合A B C表示交集中含有 a,b,c的集合取法

C(n,i)表示从n个形如A B C的集合中取出i个,算出有多少种取法

这i个集合的交集则表示同时含有这i个元素

后一项则表示其他集合任意选取,但不能一个都不选的方案数

偶加奇减,则得到全集减去这几个集合的并集,得到f(i)

 #include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const int mod=1e9+;
int n,k;
ll js[],jsinv[];
ll qpow(ll base,int y,int mo)
{
ll ans=;
while(y)
{
if(y&) ans=ans*base%mo;
base=base*base%mo;
y>>=;
}
return ans;
}
void init()
{
js[]=;
for(int i=;i<=n;i++) js[i]=js[i-]*i%mod;
jsinv[n]=qpow(js[n],mod-,mod);
for(int i=n-;i>=;i--) jsinv[i]=jsinv[i+]*(i+)%mod;
}
inline ll C(int n,int m)
{
return js[n]*jsinv[m]%mod*jsinv[n-m]%mod;
}
inline ll ask(int m)
{
ll ans=;
for(int i=,u=;i<=m;i++,u=-u)
ans=(ans+u*C(m,i)*(qpow(,qpow(,m-i,mod-),mod)-)%mod)%mod;
return ans;
}
int main()
{
scanf("%d%d",&n,&k);
init();
printf("%lld\n",(ask(n-k)*C(n,k)%mod+mod)%mod);
return ;
}

另一种等价的方法

$ans=\binom{n}{k}*\sum\limits_{i=k}^{n}(-1)^{i-k}*\binom{n-k}{i-k}*(2^{2^{n-i}}-1)$

这种方法可以理解为固定一种组合,从其他集合中选取几个进行容斥

也能算出答案

 #include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const int mod=1e9+;
int n,k;
ll js[],jsinv[];
ll qpow(ll base,int y,int mo)
{
ll ans=;
while(y)
{
if(y&) ans=ans*base%mo;
base=base*base%mo;
y>>=;
}
return ans;
}
void init()
{
js[]=;
for(int i=;i<=n;i++) js[i]=js[i-]*i%mod;
jsinv[n]=qpow(js[n],mod-,mod);
for(int i=n-;i>=;i--) jsinv[i]=jsinv[i+]*(i+)%mod;
}
inline ll C(int n,int m)
{
return js[n]*jsinv[m]%mod*jsinv[n-m]%mod;
}
int main()
{
scanf("%d%d",&n,&k);
init();
ll ans=;
for(int i=k,u=;i<=n;i++,u=-u)
ans=(ans+u*C(n-k,i-k)%mod*(qpow(,qpow(,n-i,mod-),mod)-)%mod)%mod;
printf("%lld\n",(ans*C(n,k)%mod+mod)%mod);
return ;
}

bzoj2839 集合计数 组合计数 容斥原理|题解的更多相关文章

  1. [ZJOI2010]排列计数 (组合计数/dp)

    [ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...

  2. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [FFT 组合计数 容斥原理]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

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

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

  4. 集训队8月9日(组合计数+容斥原理+Mobius函数)

    刷题数:4 今天看了组合计数+容斥原理+Mobius函数,算法竞赛进阶指南169~179页 组合计数 https://www.cnblogs.com/2462478392Lee/p/11328938. ...

  5. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

  6. [总结]数论和组合计数类数学相关(定理&证明&板子)

    0 写在前面 0.0 前言 由于我太菜了,导致一些东西一学就忘,特开此文来记录下最让我头痛的数学相关问题. 一些引用的文字都注释了原文链接,若侵犯了您的权益,敬请告知:若文章中出现错误,也烦请告知. ...

  7. ACM组合计数入门

    1 排列组合 1.1 排列 \[A_n^m=n(n-1)(n-2)\cdots(n-m+1)=\frac{n!}{(n-m)!} \] 定义:从 n 个中选择 m 个组成有序数列,其中不同数列的数量. ...

  8. 【BZOJ5491】[HNOI2019]多边形(模拟,组合计数)

    [HNOI2019]多边形(模拟,组合计数) 题面 洛谷 题解 突然特别想骂人,本来我考场现切了的,结果WA了几个点,刚刚拿代码一看有个地方忘记取模了. 首先发现终止态一定是所有点都向\(n\)连边( ...

  9. 【BZOJ5323】[JXOI2018]游戏(组合计数,线性筛)

    [BZOJ5323][JXOI2018]游戏(组合计数,线性筛) 题面 BZOJ 洛谷 题解 显然要考虑的位置只有那些在\([l,r]\)中不存在任意一个约数的数. 假设这样的数有\(x\)个,那么剩 ...

随机推荐

  1. @Bean修饰的方法参数的注入方式

    @Bean修饰的方法参数的注入方式: 方法参数默认注入方式为Autowired,即先根据类型匹配,若有多个在根据名称进行匹配. 1:复杂类型可以通过@Qualifier(value=“XXX”)限定; ...

  2. golang学习笔记----并发

    并发模型 并发目前来看比较主流的就三种: 多线程:每个线程一次处理一个请求,线程越多可并发处理的请求数就越多,但是在高并发下,多线程开销会比较大. 协程:无需抢占式的调度,开销小,可以有效的提高线程的 ...

  3. .net架构的浅谈

    ,net的架构有以下几种 1.两层架构:UI + 数据层 2.三层架构:UI + 业务层 + 数据层 3.三层 + 接口层 (把相关的业务层抽象成接口,下层来实现接口,中层是依赖) 4.三层 + 接口 ...

  4. Queue接口分析:add和offer区别,remove和poll方法到底啥区别

    Queue接口: public interface Queue<E> extends Collection<E> { /* * add方法,在不违背队列的容量限制的情况,往队列 ...

  5. JAVA中调用外部程序,并等待其退出(涉及Runtime和ProcessBuilder)

    这段时间要写一个java调用外部程序的功能,踩了几个坑,这里分享一下. 首先用的是RunTime,调用代码如下: Process pro = Runtime.getRuntime().exec(&qu ...

  6. 微服务架构 ------ 插曲 hikari连接池的配置

    开胃菜:据说hikari连接池很快,快到让另一个连接池的作者抛弃对自己连接池的维护,并且强烈推荐使用hikari 连接池目前我们项目使用的有两个 一个是Druid , 一个是 Hikari, 其中Dr ...

  7. GIT篇章(一)

    git的使用 创建代码版本 cd进入到自己希望存储代码的目录路径,并创建本地仓库.git[pycharm直接打开终端就是项目根目录了.无须cd了] 新创建的本地仓库.git是个空仓库 cd 目录路径 ...

  8. VMWare15.0手动为Mac OS10.14虚拟机安装VMWare Tools

    安装完客户机虚拟机后,无法在虚拟机和本机之间拖拽传输文件,开启虚拟机后,底部提示安装VMWare Tools,但是这里无法安装. 虽然可以联网后使用局域网工具(如FeiQ)来传输,但是老感觉不是太方便 ...

  9. 函数使用十一:BAPI_BANK_CREATE

    FI01创建银行主数据: BAPI:BAPI_BANK_CREATE *&----------------------------------------------------------- ...

  10. node 淘宝镜像

    永久使用 打开终端执行 npm config set registry https://registry.npm.taobao.org 临时使用 npm --registry https://regi ...