卡农 -- \(HNOI2011\)

$$luogu$$

$$HZOI$$


题意

给定一个 集合 $ A= { 1 \le x \le n | x } $ , 求出其 \(m\) 个不相同的且不为空集的子集,使得第 \(i\) 个元素的在所有选出的子集中出现的次数 \(appear_i \mod 2 = 0\)


题解

首先一个已知结论:

对于一个 \(A\) 这样的集合,他不同的子集个数为 \(2^n\)

那么这时我们减去空集,那么可选的为 \(2^n - 1\) 种。

你影响你最后的每个元素的出现次数的是第 \(m\) 次的选择。

若第 \(i\) 个数在前 \(m - 1\) 个子集中出现的次数为奇数,那么 \(i\) 在最后一个中必定出现。

反之就不会出现。

所以 前 \(m - 1\) 个怎么取值都行。

考虑此时 \(ans_m\) 为 \(m\) 个子集满足条件的方案数。

不考虑什么奇偶,前 \(m - 1\) 个能选的总方案数为 :

\[ans_m += C^{ m - 1 }_{2 ^ n - 1}
\]

第一种情况:若 \(1 \dots n\) 在前 \(m - 1\) 个子集中出现的次数均为偶数,则此时末尾为空集,显然不可取,所以:

\[ans_m -= ans_{m - 1}
\]

第二种情况:若所有出现次数为奇数的数构成的集合 \(B\) 已经被选入,则:

\[ans_m -= (2 ^ n - 1 - (m - 2)) \times ans_{m - 2}
\]

解释一下:

那么我们可以看做就是最后一个集合 \(=\) 第 \(m - 1\) 个集合

那前 \(m - 2\) 个肯定是符合要求的。那肯定前 \(m - 2\) 个是不重叠的那这个重叠的集合的取值种数为 $2 ^ n - 1 - (m - 1) $

最后的处理,现在定义 \(n = 2, m = 3\)

那对于这三种选法,会算成三种,但实际是一种

\[\{1\} , \{2\} , \{1 , 2\}
\]
\[\{1\} , \{1 , 2\} , \{2\}
\]
\[\{2\} , \{1 , 2\} , \{1\}
\]

注意对于前面 $ 2 $ 个集合的来说它的选择的顺序是没关系的。算成三种的原因只是因为最后的一个集合的抠出来的值不同。

所以再除以一个 $ m $

所以 \(DP\) 转移方程为:

\[dp_i = C ^ {i - 1} _ {2 ^ n - 1} - dp_{i - 1} - dp_{i - 2} \times ( 2 ^ n - 1 - ( m - 2 ) )
\]

\(code\)

格式化过的

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std ;
const int N = 1e6 + 1 ;
int dp[ N ], C[ N ] ;
const long long mod = 1e8 + 7 ;
namespace Combination {
int nueyong[ N ], sum_neo[ N ] ;
inline void lear_neoyong() {
sum_neo[ 0 ] = sum_neo[ 1 ] = 1 ;
nueyong[ 1 ] = 1 ;
nueyong[ 0 ] = 1 ; // sum[ 0 ] = sum[ 1 ] = 1 ;
for (int i = 2 ; i < N ; ++ i) {
int p = mod ;
int k = p / i ;
nueyong[ i ] = (k * (p - nueyong[ p % i ])) % p ;
sum_neo[ i ] = (nueyong[ i ] * sum_neo[ i - 1 ]) % p ;
// sum[ i ] = ( i * sum[ i - 1 ] ) % p ;
}
}
int Quick_Pow(int alpha, int beta) {
int ans = 1 ; while (beta > 0) {
if (beta & 1)
ans = (ans * alpha) % mod ; beta >>= 1 ;
alpha = (alpha * alpha) % mod ;
} return ans ;
}
} ;
using namespace Combination ;
inline int read() {
int x = 0, f = 1 ;
char c = getchar() ; while (c < '0' || c > '9') {
if (c == '-') {
f = - f ;
} c = getchar() ;
} while (c >= '0' && c <= '9') {
x = x * 10 + c - '0' ;
c = getchar() ;
} return x * f ;
}
int n, m, all_time, koul ;
signed main() {
n = read() ;
m = read() ;
lear_neoyong() ;
all_time = (((Quick_Pow(2, n) - 1) % mod) + mod) % mod ;
C[ 0 ] = 1 ;
int tot = all_time ; for (int i = 1 ; i <= m ; ++ i) {
C[ i ] = (C[ i - 1 ] * ((tot + mod) % mod)) % mod ;
tot -- ;
} dp[ 2 ] = dp[ 1 ] = 0 ; for (int i = 3 ; i <= m ; ++ i) {
int pri = (C[ i - 1 ] * sum_neo[ i - 1 ]) % mod ;
dp[ i ] = ((((pri - dp[ i - 1 ]) - ((dp[ i - 2 ] * ((all_time - i + 2) % mod + mod) % mod) % mod) + mod) %
mod) * nueyong[ i ]) % mod ;
} cout << dp[ m ] ;
}

结尾撒花 \(\color{pink}✿✿ヽ(°▽°)ノ✿\)

卡农 -- HNOI2011 -- DP&组合的更多相关文章

  1. BZOJ.2339.[HNOI2011]卡农(思路 DP 组合 容斥)

    题目链接 \(Description\) 有\(n\)个数,用其中的某些数构成集合,求构造出\(m\)个互不相同且非空的集合(\(m\)个集合无序),并满足每个数总共出现的次数为偶数的方案数. \(S ...

  2. P3214-[HNOI2011]卡农【dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P3214 题目大意 一个由\(1\sim n\)的所有整数构成的集合\(S\),求出它的\(m\)个不同非空子集满足 ...

  3. bzoj2339[HNOI2011]卡农 dp+容斥

    2339: [HNOI2011]卡农 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 842  Solved: 510[Submit][Status][ ...

  4. [HNOI2011]卡农 (数论计数,DP)

    题面 原题面 众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则. 他将声音分成 n n n 个音阶,并将音乐分成若干个片段.音乐的每个片段都是由 1 1 1 ...

  5. P3214 [HNOI2011]卡农

    题目 P3214 [HNOI2011]卡农 在被一题容斥\(dp\)完虐之后,打算做一做集合容斥这类的题了 第一次深感HNOI的毒瘤(题做得太少了!!) 做法 求\([1,n]\)组成的集合中选\(m ...

  6. 【BZOJ2339】[HNOI2011]卡农 组合数+容斥

    [BZOJ2339][HNOI2011]卡农 题解:虽然集合具有无序性,但是为了方便,我们先考虑有序的情况,最后将答案除以m!即可. 考虑DP.如果我们已经知道了前m-1个集合,那么第m个集合已经是确 ...

  7. [BZOJ2339][HNOI2011]卡农

    [BZOJ2339][HNOI2011]卡农 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见& ...

  8. BZOJ2339[HNOI2011]卡农——递推+组合数

    题目链接: [HNOI2011]卡农 题目要求从$S=\{1,2,3……n\}$中选出$m$个子集满足以下三个条件: 1.不能选空集 2.不能选相同的两个子集 3.每种元素出现次数必须为偶数次 我们考 ...

  9. [HNOI2011]卡农 题解

    题目描述 众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则.他将声音分成 n 个音阶,并将音乐分成若干个片段.音乐的每个片段都是由 1 到 n 个音阶构成的 ...

  10. [HNOI2011]卡农

    题目描述 众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则.他将声音分成 n 个音阶,并将音乐分成若干个片段.音乐的每个片段都是由 1 到 n 个音阶构成的 ...

随机推荐

  1. 修改Git Commit提交记录的用户名Name和邮箱Email

    修改Git 本次Commit提交记录的用户名Name和邮箱Email git commit --amend --author="new-name <xxx@new.com>&qu ...

  2. ZYNQ:提取PetaLinux中Linux和UBoot配置、源码

    说明 默认情况下,PetaLinux在编译完成后会删除源代码,以节省硬盘空间. 在project-spec/meta-user/conf/petalinuxbsp.conf里,添加如下内容,可以保留L ...

  3. python3 podman库

    前言 最近在使用 podman, 需要调用一些 podman的接口,podman官网提供的接口并不是很详尽,使用 unix.sock 的方式调用有一 些困难.后来测试 ai 工具时,其提供了一个比较好 ...

  4. Mysql通过frm和ibd恢复数据库

    昨天的考试过程中,有个考点的服务器蓝屏重启后发现Mysql启动不了(5.6.45 x32版本,使用innoDB),重装后无法加载原数据库记录,通过查询资料,通过frm和idb文件成功恢复了数据库记录. ...

  5. Pandas中的常用函数

    1. map.apply.applymap 参考:Pandas教程 | 数据处理三板斧--map.apply.applymap详解 在日常的数据处理中,经常会对一个DataFrame进行逐行.逐列和逐 ...

  6. eclipse取消默认工作空间的两种方法

    对于eclipse的默认的工作空间,如果不需要正常切换workspace的用户很方便,打开eclipse便自动进入默认的工作空间.而如果用户经常在多个workspace之间切换的话,启动eclipse ...

  7. Solo 开发者周刊 (第5期):打破常规,探索技术新边界

    这里会整合 Solo 社区每周推广内容.产品模块或活动投稿,每周五发布.在这期周刊中,我们将深入探讨开源软件产品的开发旅程,分享来自一线独立开发者的经验和见解.本杂志开源,欢迎投稿. 产品推荐 1. ...

  8. 【原创软件】第6期:极简SciHub论文下载器

    一.背景 因为科研需求下载英文论文,省得自己去找有效的scihub网址,特此写了一个基于c#和wpf的小软件. 二.使用方法 只需要输入doi即可,点击[打开浏览器下载论文]即可跳转浏览器进行下载.下 ...

  9. leetcode简单(数组,字符串,链表):[66, 67, 70, 83, 121, 141, 160, 169, ,206, 338]

    目录 66. 加一 67. 二进制求和 70. 爬楼梯 83. 删除排序链表中的重复元素 121. 买卖股票的最佳时机 141. 环形链表 160. 相交链表 169. 多数元素 206. 反转链表 ...

  10. oeasy教您玩转vim - 79 - # 编码格式encoding

    ​ ​ - `help encoding-name` ​ ![图片描述](https://s4.51cto.com/images/blog/202201/03083053_61d243bd719358 ...