bzoj2839 集合计数 组合计数 容斥原理|题解
集合计数
题目描述
一个有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 集合计数 组合计数 容斥原理|题解的更多相关文章
- [ZJOI2010]排列计数 (组合计数/dp)
[ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...
- 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是第二类斯特林 ...
- BZOJ2839:集合计数(容斥,组合数学)
Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007. ...
- 集训队8月9日(组合计数+容斥原理+Mobius函数)
刷题数:4 今天看了组合计数+容斥原理+Mobius函数,算法竞赛进阶指南169~179页 组合计数 https://www.cnblogs.com/2462478392Lee/p/11328938. ...
- 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是第二类斯特林 ...
- [总结]数论和组合计数类数学相关(定理&证明&板子)
0 写在前面 0.0 前言 由于我太菜了,导致一些东西一学就忘,特开此文来记录下最让我头痛的数学相关问题. 一些引用的文字都注释了原文链接,若侵犯了您的权益,敬请告知:若文章中出现错误,也烦请告知. ...
- ACM组合计数入门
1 排列组合 1.1 排列 \[A_n^m=n(n-1)(n-2)\cdots(n-m+1)=\frac{n!}{(n-m)!} \] 定义:从 n 个中选择 m 个组成有序数列,其中不同数列的数量. ...
- 【BZOJ5491】[HNOI2019]多边形(模拟,组合计数)
[HNOI2019]多边形(模拟,组合计数) 题面 洛谷 题解 突然特别想骂人,本来我考场现切了的,结果WA了几个点,刚刚拿代码一看有个地方忘记取模了. 首先发现终止态一定是所有点都向\(n\)连边( ...
- 【BZOJ5323】[JXOI2018]游戏(组合计数,线性筛)
[BZOJ5323][JXOI2018]游戏(组合计数,线性筛) 题面 BZOJ 洛谷 题解 显然要考虑的位置只有那些在\([l,r]\)中不存在任意一个约数的数. 假设这样的数有\(x\)个,那么剩 ...
随机推荐
- com.fasterxml.jackson.core.JsonGenerationException: Can not write a field name, expecting a value异常
springboot对象返回,一直报生成json异常,经过检查,发现是自己在做xss防护时对出参进行了json的处理(copy代码不可取,囧) 异常信息 这里进行了出参处理了,但实际上只要对入参处理就 ...
- SuRF : Practical Range Query Filtering with Fast Succinct Tries
1. Introduction 在数据库管理系统中查找某些关键字会导致很大的磁盘I/O开销,针对这一问题,通常会使用一个内存开销小并且常驻内存的过滤器来检测该关键字是否存.比如现在常用的bloom过滤 ...
- NetCoreApi框架搭建(二、Nlog使用配置)
本文只配置了简单文件存储 1.添加nuget包 2.添加日志配置文件nlog.config 这里配置了三个target区分不同的日志,具体配置需要自己研究,推荐链接https://www.cnblog ...
- SVN服务端安装和仓库的创建
1.安装SVN服务端 双击运行: 点击[next] 勾上复选框,点击[next] 使用默认选项,点击[next] 点击[Standard Edition]建议端口号不用443,因为Vmware占用了, ...
- 第13章 C#中的多线程
章多线程 13.1 线程概述 计算机的操作系统多采用多任务和分时设计.多任务是指在一个操作系统中开以同时运行多个程序.例如,可以在使用QQ聊天的同时听音乐,即有多个独立的任务,每个任务对应一个进程,每 ...
- 教你玩转Linux系统目录结构
Linux 内核最初只是由芬兰人林纳斯·托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的.Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POS ...
- 隐马尔科夫模型(Hidden Markov Models) 系列之五
转自:http://blog.csdn.net/eaglex/article/details/6458541 维特比算法(Viterbi Algorithm) 找到可能性最大的隐藏序列 通常我们都有一 ...
- uni-app常用 HTML5+APP 设置
1.锁定屏幕方向 锁定屏幕方向后屏幕只能按锁定的屏幕方向显示,关闭当前页面后仍然有效. 可再次调用此方法修改屏幕锁定方向或调用 unlockOrientation() 方法恢复到应用的默认值. 锁定屏 ...
- 如何用StatSVN统计SVN服务器某项目的代码量
startsvn下载地址: https://sourceforge.net/projects/statsvn/?source=typ_redirect svn下载地址: https://www.vis ...
- 编写合格的C代码(1):通过编译选项将特定警告视为错误
目录 快速设定 向错误的执念开炮,向C编译器开炮 编译警告应当被忽略吗?warning不重要吗? 个人总结的应当视作error的warning 1. 函数没有声明就使用 2. 函数虽然有声明,但是声明 ...