题目链接: [HNOI2011]卡农 题目要求从$S=\{1,2,3……n\}$中选出$m$个子集满足以下三个条件: 1.不能选空集 2.不能选相同的两个子集 3.每种元素出现次数必须为偶数次 我们考虑递推,设$f[i]$为选$i$个集合满足以上条件的方案数. 考虑容斥: 当确定了前$i-1$个集合后,要满足第三个条件的话,第$i$个集合是唯一确定的,所以总方案数为$A_{2^n-1}^{i-1}$. 去掉第$i$个集合是空集的情况,如果第$i$个集合是空集,那么前$i-1$个集合一定合法,即方…
[BZOJ2339][HNOI2011]卡农 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见"试题描述" 数据规模及约定 见"试题描述" 题解 先考虑 m 个 01 串排顺序的情况.可以发现如果定下前 m - 1 个 01 串,那么第 m 个串就可以由前面所有 01 串按位异或得出,所以方案数为 A(2n - 1, m - 1)(即除全 0 串外的所有情况选择…
2339: [HNOI2011]卡农 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 842  Solved: 510[Submit][Status][Discuss] Description 可以把集合视作有序的,当做排列做,最后再 /m!设f[i]表示选出i个集合的合法方案 选出了(i-1)个集合后,最后一个集合是唯一确定的 总数就是A(2^n - 1,i-1)但是最后确定的集合可能使方案不合法,有两种情况1.最后确定的集合为空,这种情况的方案…
考虑有序选择各子集,最后除以m!即可.设f[i]为选i个子集的合法方案数. 对f[i]考虑容斥,先只满足所有元素出现次数为偶数.确定前i-1个子集后第i个子集是确定的,那么方案数为A(2n-1,i-1). 显然不能为空集,于是去掉前i-1个已经满足限制的方案,也即f[i-1]. 然后去掉第i个子集和之前重复的情况.显然如果有重复,将这两个去掉后仍然是合法的.那么方案数为f[i-2]*(i-1)*(2n-1-(i-2)). #include<iostream> #include<cstdi…
[BZOJ2339]卡农(递推,容斥) 题面 BZOJ 题解 先简化一下题意: 在\([1,2^n-1]\)中选择不重复的\(m\)个数,使得他们异或和为\(0\)的方案数. 我们设\(f[i]\)表示选择\(i\)个数异或和为\(0\)的方案数. 直接算是很麻烦的,所以我们反过来,总数减去不合法的. 因为确定了前\(i-1\)个数最后一个数就已经知道了. 所以总方案数是\(A_{2^n-1}^{i-1}\),不合法的有两种,一种是选择了\(0\),一种是有重复. 选择了\(0\),意味着前\(…
[BZOJ2339][HNOI2011]卡农 题解:虽然集合具有无序性,但是为了方便,我们先考虑有序的情况,最后将答案除以m!即可. 考虑DP.如果我们已经知道了前m-1个集合,那么第m个集合已经是确定的了.因为内层集合的n个元素可以随便出现,那么总数就是A(2^n-1,m-1).但是可能存在不合法的情况. 1.在前m-1个集合中,n个数出现的次数已经都是偶数了,那么第m个集合为空,不合法,此时方案数为f[m-1].2.第m个集合与之前某个集合相同,那么我们不考虑这两个集合,剩下的方案数为f[i…
题目 P3214 [HNOI2011]卡农 在被一题容斥\(dp\)完虐之后,打算做一做集合容斥这类的题了 第一次深感HNOI的毒瘤(题做得太少了!!) 做法 求\([1,n]\)组成的集合中选\(m\)个不同集合且每个元素出现偶数的组合方案 无序(打乱顺序仍记为一种)通常我们对于有序的做法更简单,怎么转换呢 C组合数的公式是怎么得来的?别说你是背来的\(emmm\)(那也没有做这题的必要了) 有序\(m!\)就得到了无序的 我们考虑\(dp\),数组\(dp_i\)表示选i个不同集合的排列方案…
题意:从编号为 1~N 的音阶中可选任意个数组成一个音乐片段,再集合组成音乐篇章.要求一个音乐篇章中的片段不可重复,都不为空,且出现的音符的次数都是偶数个.问组成 M 个片段的音乐篇章有多少种.答案取模1000000007(质数). 解法:先将题目模型化:N 个数组成 M 种组合,且要求组合之间互不相等,把各组合用二进制表示对 N 个数的取舍状态之后的异或和为0.   虽然求得是组合,但我们转化为排列来做计算时更方便.假设 f[i] 表示从 n 个数中选 i 种排列的方案数.那么就是"总的排列数…
记录一下一种推组合数前缀和的方法 Trick 设\(\sum_{i = 0}^m C_n^i = S(n, m)\) \(S\)是可以递推的 \(S(n, m + 1) = S(n, m) + C_{n}^{m + 1}\) 就是加上最末尾的一项 \(S(n + 1, m) = 2S(n, m) - C_n^m\) \(S(n, m)\)可以看做是杨辉三角上的一行,而\(S(n+1, m)\)是他的下一行 考虑组合数的递推公式,除了\(C[n][m]\)这一项之外都会被计算两次. 另外如果有多组…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3398 对于这种有点巧妙的递推还是总是没有思路... 设计一个状态 f[i] 表示第 i 位置上是公牛,那么 f[i] = ∑(0<=j<i-k) f[j]: 再前缀和优化一下即可. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; ,mod=…