「BZOJ2839」集合计数
「BZOJ2839」集合计数
题目大意:
一个包含 \(n\) 个数的集合有 \(2^n\) 个子集,从这些子集中取出若干个集合(至少一个),使他们的交集的元素个数恰好为 \(k\),求方案数,答案对 \(1e9+7\) 取模。
首先考虑一个很直观的思路:我们钦定 \(k\) 个数是他们的交集,则这样的方案数为 \(\binom{n}{k}\) ,同时,包含这 \(k\) 个数的集合个数为 \(2^{n-k}\) ,每个集合有选与不选两个状态,但依据题意,不能够全部不选,所以这样得到的总方案数 \(b_k\)为
\]
但这样求出来的结果并不是我们想要的,设这些集合真实的交集集合 \(j\) 个数组成的集合为 \(A\),钦定的 \(k\) 个数组成的集合为 \(B\) ,则当\(B \subseteq A\) 时, 那么这个方案就会被统计一次,总共就会被统计 \(\binom j k\) 次。
设交集中恰好有 \(k\) 个元素的方案数为 \(a_k\),则有
\]
然后这里,我们可以利用容斥原理来推出,但更方便的是使用二项式反演,即
\]
这个式子可以通过直接将前式代入得到。
同样,二项式反演也还有另一种形式
\]
证明方法类似,在此不作赘述。
关于这道题,我们直接反演一下即可得到答案,即
\]
时间复杂度为 \(O(n)\)。
\(\texttt{Code:}\)
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll p=1e9+7;
const ll maxn=1e6+5;
ll ksm(ll a,ll b,ll p){
ll ans=1;
for(;b;b>>=1,a=1ll*a*a%p)
if(b&1) ans=1ll*ans*a%p;
return ans;
}
ll fac[maxn],inv[maxn];
ll C(ll n,ll m){
if(n<m) return 0;
return 1ll*fac[n]*inv[m]%p*inv[n-m]%p;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
ll n,k;
cin>>n>>k;
fac[0]=1;
for(ll i=1;i<=n;++i) fac[i]=1ll*fac[i-1]*i%p;
inv[n]=ksm(fac[n],p-2,p);
for(ll i=n-1;i>=0;--i) inv[i]=1ll*inv[i+1]*(i+1)%p;
ll ans=0;
for(ll i=k;i<=n;++i){
ans=(ans+1ll*((i-k)&1?(-1):(1))*(C(i,k)*C(n,i)%p*(ksm(2,ksm(2,n-i,p-1),p)%p-1+p))%p+p)%p;
}
cout<<ans<<'\n';
return 0;
}
「BZOJ2839」集合计数的更多相关文章
- 【BZOJ2839】集合计数&&【BZOJ3622】已经没有什么好害怕的了
再谈容斥原理来两道套路几乎一致的题目[BZOJ2839]集合计数Description一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交 ...
- 【BZOJ2839】集合计数(容斥,动态规划)
[BZOJ2839]集合计数(容斥,动态规划) 题面 BZOJ 权限题 Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使 ...
- AC日记——「SDOI2017」序列计数 LibreOJ 2002
「SDOI2017」序列计数 思路: 矩阵快速幂: 代码: #include <bits/stdc++.h> using namespace std; #define mod 201704 ...
- 【BZOJ2839】集合计数 组合数+容斥
[BZOJ2839]集合计数 Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数 ...
- 「 深入浅出 」集合Map
系列文章: 「 深入浅出 」java集合Collection和Map 「 深入浅出 」集合List 「 深入浅出 」集合Set 前面已经介绍完了Collection接口下的集合实现类,今天我们来介绍M ...
- 「 深入浅出 」集合Set
系列文章 「 深入浅出 」集合List 「 深入浅出 」java集合Collection和Map Set继承自Collection接口,不能包含有重复元素.本篇文章主要讲Set中三个比较重要的实现类: ...
- 「 深入浅出 」集合List
第一篇文章 「 深入浅出 」java集合Collection和Map 主要讲了对集合的整体介绍,本篇文章主要讲List相对于Collection新增的一些重要功能以及其重要子类ArrayList.Li ...
- 【BZOJ-2839】集合计数 容斥原理 + 线性推逆元 + 排列组合
2839: 集合计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 229 Solved: 120[Submit][Status][Discuss] ...
- 「Foundation」集合
一.NSArray和NSMutableArray (一)NSArray不可变数组 (1)NSArray的基本介绍 NSArray是OC中使用的数组,是面向对象的,以面向对象的形式操纵对象,是不可变数组 ...
随机推荐
- Python+Selenium - js操作
js操作:日期框 本部分涉及两个知识点:DOM树和js DOM树教程链接: https://www.w3school.com.cn/htmldom/index.asp js教程链接 https://w ...
- TVM性能评估分析(四)
TVM性能评估分析(四) Figure 1. Efficient Privacy-Preserving ML Using TVM Figure 2. Motivation: Privacy-Pre ...
- Java面试必知必会:基础
面试考察的知识点多而杂,要完全掌握需要花费大量的时间和精力.但是面试中经常被问到的知识点却没有多少,你完全可以用 20% 的时间去掌握 80% 常问的知识点. 一.基础 包括: 杂七杂八 面向对象 数 ...
- MySQL:聊一聊数据库中的那些锁
在软件开发中,程序在高并发的情况下,为了保证一致性或者说安全性,我们通常都会通过加锁的方式来解决,在 MySQL 数据库中同样有这样的问题,一方面为了最大程度的利用数据库的并发访问,另一方面又需要保证 ...
- 【模板】关于vector的lower_bound和upper_bound以及vector基本用法 STL
关于lower_bound和upper_bound 共同点 函数组成: 一个数组元素的地址(或者数组名来表示这个数组的首地址,用来表示这个数组的开头比较的元素的地址,不一定要是首地址,只是用于比较的& ...
- 手写Spring Config,最终一战,来瞅瞅撒!
上一篇说到了手写Spring AOP,来进行功能的增强,下面本篇内容主要是手写Spring Config.通过配置的方式来使用Spring 前面内容链接: 我自横刀向天笑,手写Spring IOC容器 ...
- Vue(1)Vue安装与使用
前言 Vue(读音/vjuː/,类似于view) 是一套用于构建前后端分离的框架.刚开始是由国内优秀选手尤雨溪开发出来的,目前是全球"最"流行的前端框架.使用vue开发网页很简单, ...
- 『心善渊』Selenium3.0基础 — 7、XPath轴定位详解
目录 1.XPath轴定位介绍 2.位置路径表达式概念 3.步的路径表达式范例 4.练习 使用XPath轴方式,可根据文档中元素的相对位置,来进行元素的定位.例如:先找到一个相对好定位的元素,在根据与 ...
- 『无为则无心』Python基础 — 12、Python运算符详细介绍
目录 1.表达式介绍 2.运算符 (1)运算符的分类 (2)算数运算符 (3)赋值运算符 (4)复合赋值运算符 (5)比较运算符 3.逻辑运算符 拓展1:数字之间的逻辑运算 拓展2:Python中逻辑 ...
- 给STM32MP157C-DK2烧录固件
环境: 一台PC(window/linux) STM32CubeProgrammer 我下载到的是 2.1 版本(19\07\10下载的) 里面的文件是: 里面有 3 个文件,分别window.Lin ...