[HNOI2011]卡农

原创 2012年03月29日 08:33:47

这道题是day2压轴……去年我没做出来,然后一直以为很难……

昨天做了一下发现这题超过瘾的……是个数学题……写出来的代码超短……

但是很难想……

首先考虑所有的集合:除掉空集以后共有2^n-1个

当确定了前m-1个集合以后,第m个集合就确定了,因为要求所有的数出现偶数次

这道题要求不记顺序,但是记顺序的更好算一点,然后在最后除一个m!即可

那么我们记f[i]为前i个集合记顺序的方案数,g[i]为A(2^n-1,i),即在2^n-1个集合里取i个集合的排列数

很显然f[i]等于g[i]减去某个数,因为算重了

考虑哪些是算重的:

1.前i-1个集合已经保证了所有的数出现偶数次,那么第i个集合就是空集,要减去这种情况,即减去f[i-1]

2.第i个集合和前i-1个集合中的某一个重复,除掉这个重复的集合,有f[i-2]种方案,这个重复的集合可能的位置有i-1种,重复的集合可能的取法有2^n-1-(i-2)种(跟剩下的m-2种不同)

那么f[i]=g[i-1]-f[i-1]-f[i-2]*(i-1)*(2^n-1-(i-2))

最后除个m!,模的数是质数,可以求逆元……然后完了

如果计数的部分解决了就很简单……关键是想不想得到啊……

//Lib
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
//Macro
#define	rep(i,a,b)	for(int i=a,tt=b;i<=tt;++i)
#define	drep(i,a,b)	for(int i=a,tt=b;i>=tt;--i)
#define	erep(i,e,x)	for(int i=x;i;i=e[i].next)
#define	irep(i,x)	for(__typeof(x.begin()) i=x.begin();i!=x.end();i++)
#define	read()	(strtol(ipos,&ipos,10))
#define	sqr(x)	((x)*(x))
#define	pb	push_back
#define	PS	system("pause");
typedef	long long	ll;
typedef	pair<int,int>	pii;
const int oo=~0U>>1;
const double inf=1e100;
const double eps=1e-6;
string name="canon", in=".in", out=".out";
//Var
ll f[1000008],mi,pre[1000008],mod=100000007,n,m,tmp=1;
ll power(ll a,int b)
{
	if(b==0)return 1;
	ll ret=power(a,b>>1);
	ret=ret*ret%mod;
	if(b&1)ret=ret*a%mod;
	return ret;
}
void Dec(ll &a,ll b){a-=b;if(a<0)a+=mod;}
void Init()
{
	scanf("%d%d",&n,&m);
	mi=power(2,n);mi--;
	//solve A(2^n-1,i)
	pre[0]=1;
	rep(i,1,m)pre[i]=pre[i-1]*(mi-i+1)%mod;
} 
void Work()
{
	f[1]=0;f[2]=0;
	rep(i,3,m)
	{
		f[i]=pre[i-1];
		Dec(f[i],f[i-1]);
		Dec(f[i],f[i-2]*(i-1)%mod*(mi-(i-2))%mod);
	}
	rep(i,2,m)tmp=tmp*i%mod;
	cout<<f[m]*power(tmp,mod-2)%mod<<endl;
}
int main()
{
	Init();
	Work();
//	PS;
	return 0;
}


相关文章推荐

BZOJ 2339: [HNOI2011]卡农

2011完结撒花 这题一眼看过去,裸的Lucas定理?????? 赶紧写了一发,WA了QAQ 发现题目竟然还有限制,太无情了 所以我们还是先简化一下问题,比如说把组合这个限制去掉,变成排列 ...
  • nlj1999
  • nlj1999
  • 2016年04月06日 19:12
  • 326

BZOJ2339: [HNOI2011]卡农

Description Input Output Sample Input Sample Output HINT Source Day2

【bzoj2339】【HNOI2011】【卡农】【组合数学+dp】

Description 题解: 我们先把它变成有序的,最后除一个m! 对于有序的方案数我们考虑补集转换。 首先所有的子集个数应该是2^n-1; 我们定义f[i...

[bzoj2339][HNOI2011]卡农

一道伤脑筋好题……感觉要数学非常好才能做,至于我本人只能看一眼题解orz了…… 代码核心部分并不长: #include #include #include #include #include usi...

因为卡农,重拾《我的野蛮女友》

【题记】周末,无意间听到了《卡农》的钢琴版,觉得很好听。查阅资料后发现,《卡农》有很多个版本,有用各种不同的乐器组合演奏的,都很不错。但我还是特别喜欢钢琴的声音,很悠扬,直达心底。机缘巧合之下我发现《...
  • whuslei
  • whuslei
  • 2011年09月03日 14:42
  • 2261

清新迷人《Our Canon in D》我们的D大调卡农

清新迷人《Our Canon in D》我们的D大调卡农I wrote a song for you我为你写了一首歌I don't know if you'll listen to不知道你会不会听到B...

用matlab弹奏卡农

% Cripple Pachebel's Canon on Matlab % Have fun fs = 44100; % sample rate dt = 1/fs; T16 = 0.125; t1...

ssoj1306卡农(canon)(组合数学+乘法逆元)

题目描述 众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则。他将声音分成n个音阶,并将音乐分成若干个片段。音乐的每个片段都是由1到n个音阶构成的和声,即从...
  • kaqiur
  • kaqiur
  • 2015年09月04日 16:06
  • 326

卡农背后的故事

你有听说过关于提拉米苏的传说么?   『二战时期,一个意大利士兵要出征了,可是家里已经什么也没有了。爱他的妻子为了给他准备干粮,把家里所有能吃的饼干、面包,全做进了一个糕点里,那个糕点就叫提拉米苏。每...
  • adan529
  • adan529
  • 2011年05月31日 12:55
  • 998

Matlab演奏卡农

  • 2013年06月19日 09:29
  • 15KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[HNOI2011]卡农
举报原因:
原因补充:

(最多只允许输入30个字)