[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
  • 351

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

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

[HNOI2011]卡农

这道题是day2压轴……去年我没做出来,然后一直以为很难…… 昨天做了一下发现这题超过瘾的……是个数学题……写出来的代码超短…… 但是很难想…… 首先考虑所有的集合:除掉空集以后共有2^n-1个...
  • OrpineX
  • OrpineX
  • 2012年03月29日 08:33
  • 2039

BZOJ2339: [HNOI2011]卡农

Description Input Output Sample Input Sample Output HINT Source Day2
  • doctor_godder
  • doctor_godder
  • 2015年12月04日 21:54
  • 657

bzoj2339: [HNOI2011]卡农

排列组合、动态规划
  • FSAHFGSADHSAKNDAS
  • FSAHFGSADHSAKNDAS
  • 2017年03月03日 15:13
  • 147

2339: [HNOI2011]卡农

用二进制表示一个音符的集合,那么可用的集合就有2n−12^n-1种(空集不可用),那么一段音乐所有音符都含偶数个就可以转化成一段二进制的异或和为0 用f[i]f[i]表示nn个音符可用的情况下,分成...
  • L_0_Forever_LF
  • L_0_Forever_LF
  • 2016年10月31日 08:39
  • 257

排列 [HNOI2011]卡农

问题 A: [HNOI2011]卡农 时间限制: 1 Sec 内存限制: 128 MB 题目描述 共有2^n-1种片段组合方式。设数字i出现次数ai,选i个片段是合法总方案数为fi。 这...
  • QTY2001
  • QTY2001
  • 2017年08月27日 12:27
  • 87

[bzoj2339][HNOI2011]卡农

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

洛谷 P3214 [HNOI2011]卡农

计数问题,排列组合
  • chai_jing
  • chai_jing
  • 2017年04月21日 09:08
  • 211
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[HNOI2011]卡农
举报原因:
原因补充:

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