[HNOI2011] 卡农 题解

这题实在是巧妙,值得记录下来。

题目描述

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

他将声音分成 \(n\) 个音阶,并将音乐分成若干个片段。音乐的每个片段都是由 \(1\)\(n\) 个音阶构成的和声,即从 \(n\) 个音阶中挑选若干个音阶同时演奏出来。

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

现在的问题是:小余想知道包含 \(m\) 个片段的音乐一共有多少种。
两段音乐 \(a\)\(b\) 同种当且仅当将 \(a\) 的片段重新排列后可以得到 \(b\)。例如:假设 \(a\)\(\{\{1,2\},\{2,3\}\}\)\(b\)\(\{\{2,3\},\{1,2\}\}\),那么 \(a\)\(b\) 就是同种音乐。

答案对 \(10^8+7\) 取模。

\(n ,m \leqslant 10^6\)

思路点拨

本题中,对于一种合法方案有三种约束:

  • 每一种音符都出现偶数次

  • 每一个片段非空,并且互不相同

  • 最终产生的片段的集合没有顺序之分

首先,第三种限制我们是没有必要考虑的,我们可以按照顺序分配。这样答案除 \(m!\) 消除顺序。

剩下两种我们并不清楚。但是我们可以从每一个集合放那些数的角度去考虑,因为第二个约束和过大的数据范围令我们无法记录每一个集合有哪些数。

定义 \(f_i\) 表示当 \(m=i\) 的时候,有多少种合法方案。发现,前 \(i-1\) 个集合可以推出 \(i\) 集合需要放什么。如果某一个音符在前 \(i-1\) 个集合出现了奇数次,那么在集合 \(i\) 一定会出现;如果一个音符在前 \(i-1\) 个集合出现了偶数次,那么在集合 \(i\) 就一定不出现。我们需要保证全部 \(i\) 个合法嘛。

在不考虑存在第一,第二个限制的情况下,这个总方案数就是 \(A_{2^n-1}^{i-1}\) 。因为非空集合一定有 \(2^n-1\) 种,两两集合互补相同并且有顺序之分,所以适用排列数。但是我们需要除去片段相同,以及第 \(i\) 个集合为空的情况。比如说,如果前 \(i-1\) 个集合中,每一个音符出现的次数都是偶数(\(f_{i-1}\) 种),那么集合 \(i\) 就是空的。所以 \(f_i=A_{2^n-1}^{i-1}-f_{i-1}\)

还有,我们需要去除集合相同的情况,考虑容斥,我们去让集合 \(i\) 与其余集合相同。我们在前面 \(i-1\) 个集合选取一个集合,让集合 $i $ 与之相同,此时每一个音符都是出现了偶数次,剩下的 \(i-2\) 个集合都需要合法。合法方案也比较好计算,\(f_{i-2}\) , 接下来我们乘 \(2^n-1-(i-2)\) 种方案。

Q:集合 \(i\) 不可以与前面的两个及以上集合相同吗?

A:前面的集合都不相同,所以只会与一个集合相同。

为什么是 \(2^n-1-(i-2)\) ?对于集合 \(i\) 和于其相同的那个集合,就是总方案减去另外 \(i-2\) 个集合的方案。

最终,递推式就是 \(f_i=A_{2^n-1}^{i-1}-f_{i-1}-f_{i-2} \times (i-1) \times (2^n-1-(i-2))\)

时间复杂度 \(O((n+m) \log mod)\) 。可以通过本题。

posted @ 2023-09-22 15:46  Diavolo-Kuang  阅读(24)  评论(1编辑  收藏  举报