卡农题解
来源:互联网 发布:springmvc网站源码 编辑:程序博客网 时间:2024/04/27 14:16
题目描述
众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则。他将声音分成n个音阶,并将音乐分成若干个片段。音乐的每个片段都是由1到n个音阶构成的和声,即从n个音阶中挑选若干个音阶同时演奏出来。为了强调与卡农的不同,他规定任意两个片段所包含的音阶集合都不同。同时为了保持音乐的规律性,他还规定在一段音乐中每个音阶被奏响的次数为偶数。现在的问题是:小余想知道包含m个片段的音乐一共有多少种。两段音乐a和b同种当且仅当将a的片段重新排列后可以得到b。例如:假设a为{{1,2},{2,3}},b为{{3,2},{2,1}},那么a与b就是同种音乐。由于种数很多,你只需要输出答案模100000007(质数)的结果。
输入
从文件input.txt中读入数据,输入文件仅一行,具体是用空格隔开的两个正整数n和m,分别表示音阶的数量和音乐中的片段数。20%的数据满足n,m≤5,50%的数据满足n,m≤3000,100%的数据满足n,m≤1000000。
输出
输出文件output.txt仅包含一个非负整数,表示音乐的种数模100000007的结果。
样例输入
2 3
样例输出
1
提示
样例解释:音乐为{{1},{2},{1,2}}
想法
- 初看题目是发现是一个子集选取的计数问题 很容易想到容斥
- 观察到一个重要的性质 如果前i-1个集合已经确定那么 第i个集合就确定了 因为要满足每一元素出现的次数为偶数(该性质当时是由m=1 m=2的情况递推而来,同时也得到了当m=1,m=2时答案应该为0)
- 减掉的部分有①第i个集合为空集的情况②第i个集合与之前的某项重复
- 要注意C是不好求的而A却是好球的 完全可以先求A再除以m!
算法
- 用f[i]表示选到第i个集合的方案数
- f[i]=g[i-1] (g[i]为总数)-f[i-1] (第i项是空集)-f[i-2](i-1)(2^n-1-(i-2)) (第i项与之前的重复)
- f[1]=f[2]=0 ans=f[m]/m!
代码
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <string>#include <cstring>#include <cmath>#define MAXN 1000005using namespace std;int n,m;typedef long long ll;const ll mod=100000007;ll f[MAXN],g[MAXN],o;inline ll pow(ll a,ll b,ll p){ ll r=1,base=a; while(b) { if(b&1)r=r*base%p; base=base*base%p; b>>=1; } return r%mod;}/*inline ll pls(ll a,ll b){ ll res=1,cnt=1; for (int i=1;i<=a;i++)res=res*i%mod; for (int i=1;i<=(a-b);i++)cnt=cnt*i%mod; return (res*pow(cnt,mod-2,mod))%mod;}*/int main(){ //freopen("canon.in","r",stdin); //freopen("canon.out","w",stdout); scanf("%d%d",&n,&m); o=pow(2,n,mod)-1; g[1]=o; for (int i=2;i<=m;i++) g[i]=g[i-1]*(o-i+1)%mod; f[1]=f[2]=0; for (int i=3;i<=m;i++) { f[i]=g[i-1]-f[i-1]; if(f[i]<0)f[i]+=mod; f[i]-=f[i-2]*(i-1)%mod*(o-(i-2))%mod; if(f[i]<0)f[i]+=mod; } o=1; for (int i=1;i<=m;i++)o=o*i%mod; cout<<f[m]*pow(o,mod-2,mod)%mod<<endl; return 0;}
0 0
- 卡农题解
- 卡农
- 卡农故事
- [HNOI2011]卡农
- 卡农和赋格
- D大调卡农历史背景
- 卡农背后的故事
- Matlab版《卡农》《最炫名族风》
- Matlab-音乐-卡农
- 卡农背后的含义
- BZOJ2339: [HNOI2011]卡农
- BZOJ 2339: [HNOI2011]卡农
- [bzoj2339][HNOI2011]卡农
- 2339: [HNOI2011]卡农
- 用matlab弹奏卡农
- bzoj2339: [HNOI2011]卡农
- 洛谷 P3214 [HNOI2011]卡农
- 利用MATLAB演奏卡农
- Java学习笔记07 集合框架
- Runloop笔记
- iOS开发常用的第三方类库
- 设计模式——策略模式
- 总理眼中的“分享经济”为何会成为全球经济发展助推力?
- 卡农题解
- LeetCode---Submission Details
- 【烙铁使用规范】—— 烙铁使用、温度测量规范
- 用位运算实现四则运算之加减乘除
- ASP调用WebService转化成JSON数据,附json.min.asp
- CSS之Max-Width
- Ubuntu常見命令汇总
- 加速app store访问速度
- C#之IEnumerable和IEnumerator