题面

原题面

众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则。

他将声音分成

n

n

n 个音阶,并将音乐分成若干个片段。音乐的每个片段都是由

1

1

1 到

n

n

n 个音阶构成的和声,即从

n

n

n 个音阶中挑选若干个音阶同时演奏出来。

为了强调与卡农的不同,他规定任意两个片段所包含的音阶集合都不同。同时为了保持音乐的规律性,他还规定在一段音乐中每个音阶被奏响的次数为偶数。(注:“一段音乐”指整个曲子)

现在的问题是:小余想知道包含

m

m

m 个片段的音乐一共有多少种。
两段音乐

a

a

a 和

b

b

b 同种当且仅当将

a

a

a 的片段重新排列后可以得到

b

b

b。例如:假设

a

a

a 为

{

{

1

,

2

}

,

{

2

,

3

}

}

\{\{1,2\},\{2,3\}\}

{{1,2},{2,3}},

b

b

b 为

{

{

2

,

3

}

,

{

1

,

2

}

}

\{\{2,3\},\{1,2\}\}

{{2,3},{1,2}},那么

a

a

a 与

b

b

b 就是同种音乐。

答案对

1

0

8

+

7

10^8+7

108+7 取模。

输入格式

仅一行两个正整数

n

,

m

n,m

n,m 。

输出格式

输出一行一个整数表示答案。

输入输出样例

输入 #1

2 3

输出 #1

1

说明/提示

【数据范围】
对于

20

%

20\%

20% 的数据,

1

n

,

m

5

1\le n,m \le 5

1≤n,m≤5;
对于

50

%

50\%

50% 的数据,

1

n

,

m

3000

1\le n,m \le 3000

1≤n,m≤3000;
对于

100

%

100\%

100% 的数据,

1

n

,

m

1

0

6

1\le n,m \le 10^6

1≤n,m≤106 。

【样例解释】
音乐为

{

{

1

}

,

{

2

}

,

{

1

,

2

}

}

\{\{1\},\{2\},\{1,2\}\}

{{1},{2},{1,2}} 。

题解

往容斥上面想,但是别想多了。

看了别人的题解发现其实并不难。

首先应该清楚,由于每个片段不相同,所以题目中关于 “同种音乐” 的限制可以去除掉,最后再乘上

(

m

!

)

1

(m!)^{-1}

(m!)−1 就是了。

然后,结合 DP 来容斥,我们相当于要达到三个条件:

  • 每一种音阶出现次数是偶数。
  • 无空集。
  • 不存在两片段相同。

我们令

d

p

[

i

]

\mathrm{dp}[i]

dp[i] 表示前

i

i

i 个片段满足上述条件的方案数。

按照容斥的思路,我们应该先把全集求出来,再依次减去不合法。但是很容易发现,要把不符合第一个条件的去掉极其困难。

我们其实可以先求出只满足第一条的方案总数。有一个发现:如果随意确定了前

i

1

i-1

i−1 个片段,那么为了满足第一个条件,可以直接据此推出第

i

i

i 个片段。那么我们就可以定这个方案数为:

A

2

n

1

i

1

A_{2^n-1}^{i-1}

A2n−1i−1​ ,意为确定前

i

1

i-1

i−1 个片段。这样做还有一个好处,那就是单独看前

i

1

i-1

i−1 个片段时,都是满足第二条和第三条限制的。

这就给我们的容斥带来了极大的便利。去除空集情况,达到第二条限制,很简单,如果有空集就一定是第

i

i

i 个片段空集,那么前

i

1

i-1

i−1 个片段就满足了三个条件,因此有空集的不合法情况数为

d

p

[

i

1

]

\mathrm{dp}[i-1]

dp[i−1] 。

接下来要去除存在片段相同的情况。由于前

i

1

i-1

i−1 个片段没有彼此相同的,因此只能是第

i

i

i 个片段与前面的片段相同,我们就令其为第

j

j

j 个片段。我们在

1

1

1 到

i

1

i-1

i−1 中枚举

j

j

j ,一共

i

1

i-1

i−1 种情况,再确定

i

i

i 和

j

j

j 具体应该为哪一种组合,由于

j

j

j 在前面

i

1

i-1

i−1 个片段中是独一无二的,所以一共有

2

n

1

(

i

2

)

=

2

n

i

+

1

2^n-1-(i-2)=2^n-i+1

2n−1−(i−2)=2n−i+1 种选择。

然后把

i

i

i 和

j

j

j 同时拿走,剩下的

i

2

i-2

i−2 个位置同时满足三个条件,故片段相同的不合法情况数为

d

p

[

i

2

]

(

i

1

)

(

2

n

i

+

1

)

{\rm dp}[i-2]*(i-1)*(2^n-i+1)

dp[i−2]∗(i−1)∗(2n−i+1) 。

综上,总的转移方程为:

d

p

[

i

]

=

A

2

n

1

i

1

d

p

[

i

1

]

d

p

[

i

2

]

(

i

1

)

(

2

n

i

+

1

)

{\rm dp}[i]=A_{2^n-1}^{i-1}-{\rm dp}[i-1]-{\rm dp}[i-2]*(i-1)*(2^n-i+1)

dp[i]=A2n−1i−1​−dp[i−1]−dp[i−2]∗(i−1)∗(2n−i+1) 。时间复杂度

O

(

n

)

O(n)

O(n) 。

关于排列数

A

2

n

1

i

1

A_{2^n-1}^{i-1}

A2n−1i−1​ 的计算,它其实就是最多

m

1

m-1

m−1 个数相乘。

CODE

#include<map>
#include<cmath>
#include<queue>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1000005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
void putuint(int x) {
if(!x) return ;
putuint(x/10);putchar(x%10+'0');
}
void putint(int x) {if(x==0)putchar('0');if(x<0)putchar('-'),x=-x;putuint(x);} const int MOD = 100000007;
int n,m,i,j,s,o,k;
int qkpow(int a,int b) {
int res = 1;
while(b > 0) {
if(b & 1) res = res *1ll* a % MOD;
a = a *1ll* a % MOD; b >>= 1;
}return res;
}
int fac[MAXN]={1,1},inv[MAXN]={1,1},invf[MAXN]={1,1};
int dp[MAXN];
int main() {
n = read();m = read();
for(int i = 2;i <= n||i <= m;i ++) {
fac[i] = fac[i-1] *1ll* i % MOD;
inv[i] = (MOD-inv[MOD%i]) *1ll* (MOD/i) % MOD;
invf[i] = invf[i-1] *1ll* inv[i] % MOD;
}
dp[0] = 1;dp[1] = 0;
int po = qkpow(2,n)-1,A = 1,ful = po;
for(int i = 2;i <= m;i ++) {
A = A *1ll* po % MOD;
(po += MOD-1) %= MOD;
dp[i] = (0ll+ A +MOD- dp[i-1] +MOD- dp[i-2] *1ll* (i-1) % MOD *1ll* (ful +MOD- (i-2)) % MOD) % MOD;
}
int as = dp[m] *1ll* invf[m] % MOD;
printf("%d\n",as);
return 0;
}

[HNOI2011]卡农 (数论计数,DP)的更多相关文章

  1. Luogu3214 HNOI2011 卡农 组合、DP

    传送门 火题qwq 我们需要求的是满足元素个数为\(M\).元素取值范围为\([1,2^n-1]\).元素异或和为\(0\)的集合的数量. 首先我们可以计算元素有序的方案数(即计算满足这些条件的序列的 ...

  2. 洛谷 P3214 - [HNOI2011]卡农(线性 dp)

    洛谷题面传送门 又是一道我不会的代码超短的题( 一开始想着用生成函数搞,结果怎么都搞不粗来/ll 首先不妨假设音阶之间存在顺序关系,最终答案除以 \(m!\) 即可. 本题个人认为一个比较亮的地方在于 ...

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

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

  4. P3214 [HNOI2011]卡农

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

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

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

  6. [BZOJ2339][HNOI2011]卡农

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

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

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

  8. [HNOI2011]卡农

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

  9. [HNOI2011]卡农 题解

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

随机推荐

  1. C++对象间通信组件,让C++对象“无障碍交流”

    介绍 这是很久之前的一个项目了,最近刚好有些时间,就来总结一下吧! 推荐初步熟悉项目后阅读本文: https://gitee.com/smalldyy/easy-msg-cpp 从何而来 这要从我从事 ...

  2. vue2升级vue3:vue2 vue-i18n 升级到vue3搭配VueI18n v9

    项目从vue2 升级vue3,VueI18n需要做适当的调整.主要是Vue I18n v8.x 到Vue I18n v9 or later 的变化,其中初始化: 具体可以参看:https://vue- ...

  3. BUUCTF-easycap

    easycap 看这个题目应该是流量包来的,wireshark打开即可.没什么特征,直接打开第一个包发现flag

  4. VueX的模块你知道多少?

    为什么会出现VueX的模块呢?当你的项目中代码变多的时候,很难区分维护.那么这时候Vuex的模块功能就这么体现出来了. 那么我们就开始吧!一.模块是啥? /* eslint-disable no-un ...

  5. Array 数组filter()方法,遍历数组返回符合条件的一个新数组

    <script> const arr = [ { id: 1, name: "aa", isDone: false }, { id: 2, name: "bb ...

  6. NC14301 K-th Number

    NC14301 K-th Number 题目 题目描述 Alice are given an array A[1..N] with N numbers. Now Alice want to build ...

  7. 阿里云有奖体验:用PolarDB-X搭建一个高可用系统

    体验简介 场景将提供一台配置了CentOS 8.5操作系统和安装部署PolarDB-X集群的ECS实例(云服务器).通过本教程的操作,带您体验如何使用PolarDB-X搭建一个高可用系统,通过直接ki ...

  8. PHP生成图形验证码

    在建站过程中,很多时候都会需要用户验证验证码等操作,比如:注册.登录.发表评论.获取资源等等,一方面可以验证当前用户的行为是否是爬虫.机器人等情况,给网站数据统计产生影响:另一方面可以防止用户大量刷取 ...

  9. 贝壳自动化测试平台sosotest 学习记录

    手工测试VS自动化测试 用例执行: 手动执行 自动执行 是否需要些脚本: 需要 不需要 测试报告生成: 手动 自动 常见的测试技术 关键字驱动的测试框架 RobotFRamework 单元测试框架 自 ...

  10. SpringBoot自定义starter开发分布式任务调度实践

    概述 需求 在前面的博客<Java定时器演进过程和生产级分布式任务调度ElasticJob代码实战>中,我们已经熟悉ElasticJob分布式任务的应用,其核心实现为elasticjob- ...