题意:从编号为 1~N 的音阶中可选任意个数组成一个音乐片段,再集合组成音乐篇章。要求一个音乐篇章中的片段不可重复,都不为空,且出现的音符的次数都是偶数个。问组成 M 个片段的音乐篇章有多少种。答案取模1000000007(质数)。

解法:先将题目模型化:N 个数组成 M 种组合,且要求组合之间互不相等,把各组合用二进制表示对 N 个数的取舍状态之后的异或和为0。   虽然求得是组合,但我们转化为排列来做计算时更方便。假设 f[i] 表示从 n 个数中选 i 种排列的方案数。那么就是“总的排列数 - 第 i 个片段为空(0)- 第 i 个片段与之前的 i-1 个片段中的一个重复”,而组合数就只需再除以“ i ! ”。由于递推的思想,我们只考虑第 i 个片段,之前的状态用 f[ ] 表示。
   于是,f[i] =    P(2^n-1,i-1) (由于要求异或和为0,据前 i-1 个片段就能确定第 i 个片段的状态了)
                     -  f[i-1]  (组成 i-1 个片段的方案数) 
                     -  (i-1) * [2^n-1-(i-2)] * f[i-2] 。(乘法原理{分步},位置、唯一的重复的状态、排列数)

另外,P(n,m)=n!/(n-m)!,所以 P(n,i)=n!/(n-i)!=n!/[n-(i-1)] * (n-(i-1))=P(n,i-1)*[n-(i-1)]。
   由于模的数是质数,可利用费马小定理求逆元。我昨天的一篇博文有提到:【poj 1284】Primitive Roots(数论--欧拉函数 求原根个数){费马小定理、欧拉定理}

 1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<algorithm>
5 #include<iostream>
6 using namespace std;
7 #define mod 100000007
8 #define N 1000010
9 typedef long long LL;
10
11 LL f[N],P[N];
12 LL qpow(LL x,int k)
13 {
14 LL ret=1;
15 while (k)
16 {
17 if (k&1) ret=(ret*x)%mod;
18 x=(x*x)%mod, k>>=1;
19 }
20 return ret;
21 }
22 LL ny(LL x) {return qpow(x,mod-2);}
23 int main()
24 {
25 int n,m; LL p,mm=1;
26 scanf("%d%d",&n,&m);
27 p=(qpow(2,n)-1+mod)%mod;
28 P[0]=1, f[0]=1;
29 P[1]=p, f[1]=0;//f[1]=0;
30 for (int i=2;i<=m;i++)
31 {
32 f[i]=((P[i-1]-f[i-1]+mod)%mod-((i-1)*(p-(i-2))%mod*f[i-2])%mod+mod)%mod;
33 P[i]=(P[i-1]*((p-i+1)+mod)%mod)%mod;
34 mm=(mm*i)%mod;
35 }
36 printf("%lld\n",(f[m]*(ny(mm)%mod))%mod);
37 return 0;
38 }

【bzoj 2339】[HNOI2011]卡农(数论--排列组合+逆元+递推)的更多相关文章

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

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

  2. bzoj 2339: [HNOI2011]卡农

    Description Solution 比较难想.... 我们先考虑去掉无序的这个条件,改为有序,最后除 \(m!\) 即可 设 \(f[i]\) 表示前\(i\)个合法集合的方案数 明确一点: 如 ...

  3. 2339: [HNOI2011]卡农

    Description 首先去除顺序不同算一种的麻烦,就是最后答案除以总片段数\(2^m-1\) 设\(f_i\)表示安排\(i\)个片段的合法种类 那么对于任何一个包含\(i-1\)个片段的序列(除 ...

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

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

  5. P3214 [HNOI2011]卡农

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

  6. [BZOJ2339][HNOI2011]卡农

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

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

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

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

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

  9. HYSBZ(BZOJ) 4300 绝世好题(位运算,递推)

    HYSBZ(BZOJ) 4300 绝世好题(位运算,递推) Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<= ...

随机推荐

  1. 【MySQL 基础】MySQ LeetCode

    MySQL LeetCode 175. 组合两个表 题目描述 表1: Person +-------------+---------+ | 列名 | 类型 | +-------------+----- ...

  2. SpringBoot整合Shiro完成验证码校验

    SpringBoot整合Shiro完成验证码校验 上一篇:SpringBoot整合Shiro使用Redis作为缓存 首先编写生成验证码的工具类 package club.qy.datao.utils; ...

  3. Shiro的认证与授权

    shiro实战教程 一.权限管理 1.1什么是权限管理 基本上涉及到用户参与的系统都需要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以 ...

  4. Docker 镜像管理及基础命令(二)

    Docker 常用命令: ## Docker 登录下载镜像: docker login # 登录官方hub.docker.com docker pull nginx:alpine # 下载nginx的 ...

  5. awk -v参数

    -v var=val --assign var=val Assign the value val to the variable var, before execution of the progra ...

  6. 三种梯度下降算法的区别(BGD, SGD, MBGD)

    前言 我们在训练网络的时候经常会设置 batch_size,这个 batch_size 究竟是做什么用的,一万张图的数据集,应该设置为多大呢,设置为 1.10.100 或者是 10000 究竟有什么区 ...

  7. 误删除SAP ECC中的profile文件

    环境:ECC6.0 EHP4  FOR ORACLE ON WINDWS X64下 今天在RZ10配置系统参数文件的时候,不小心错删除了instance profile文件,这下惨了,这是操作系统层级 ...

  8. VMware下安装Ubantu 18.04

    一.VIM安装及配置 1.安装VIM sudo apt-get install vim 二.拼音输入法以及搜狗拼音输入法安装 1.安装Fcitx输入框架 sudo apt-get install fc ...

  9. Scalable Go Scheduler Design Doc

    https://docs.google.com/document/d/1TTj4T2JO42uD5ID9e89oa0sLKhJYD0Y_kqxDv3I3XMw/ Scalable Go Schedul ...

  10. python RecursionError: maximum recursion depth exceeded while calling

    import copyimport sys # 导入sys模块sys.setrecursionlimit(8192) # 将默认的递归深度修改为r = sys.getrecursionlimit()_ ...