Bzoj4402 Claris的剑
Submit: 270 Solved: 152
Description
Claris想要铸一把剑,这把剑必须符合他的审美,具体来说,我们可以把这把剑的不同地方的宽度看成一个序列,这个序列要满足以下条件:
1.每个元素都是正整数(你的宽度不可能是负数吧)
2.每个元素不能超过M,太宽了如果比Claris身高还高怎么办(你可以认为Claris的身高就是M)
3.相邻两个元素的差的绝对值必须是1(如果是0,则这个地方不是锯齿,杀伤力不够,如果太大,又太丑了)
4.第一个元素的值必须是1(剑尖必须是最窄的地方)
他想知道有多少把长度不超过N(即宽度的序列长度不超过N)的合法的本质不同的剑。
我们认为两把剑本质不同,当且仅当存在至少一个宽度,在两把剑的宽度序列里面出现次数不一样。
比如{1,2,3}和{1,3,2}是本质相同的
{1,2,3}和{1,2,1}则是本质不同的
Input
只有两个整数,表示N,M (数据保证$N,M \leq 2000000$)
Output
只有一个整数,表示答案对$10^9+7$取模的结果
Sample Input
5 3
Sample Output
9
HINT
样例解释
所有本质不同的合法的剑有如下:
{1}
{1,2}
{1,2,3}
{1,2,1}
{1,2,3,2}
{1,2,1,2}
{1,2,3,2,3}
{1,2,3,2,1}
{1,2,1,2,1}
Source
题解传送门 http://blog.csdn.net/sdfzyhx/article/details/72771793
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #define LL long long 7 using namespace std; 8 const int mod=1e9+7; 9 const int mxn=2000010; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 int fac[mxn],inv[mxn]; 17 void init(int n){ 18 int mxn=n+1; 19 fac[0]=fac[1]=1;inv[0]=inv[1]=1; 20 int i,j; 21 for(i=2;i<mxn;i++){ 22 fac[i]=(LL)fac[i-1]*i%mod; 23 inv[i]=((-mod/i*(LL)inv[mod%i])%mod+mod)%mod; 24 } 25 for(i=2;i<mxn;i++)inv[i]=(LL)inv[i-1]*inv[i]%mod; 26 return; 27 } 28 int C(int n,int m){ 29 return (LL)fac[n]*inv[m]%mod*inv[n-m]%mod; 30 } 31 int n,m; 32 int main(){ 33 int i,j; 34 n=read();m=read();init(n); 35 LL ans=0; 36 if(n && m)ans=1; 37 m=min(n,m); 38 for(i=2;i<=m;i++){ 39 ans+=C((n-i)/2+i-1,i-1);if(ans>=mod)ans-=mod; 40 if(n-i-1>=0)ans+=C((n-i-1)/2+i-1,i-1);if(ans>=mod)ans-=mod; 41 } 42 printf("%lld\n",ans); 43 return 0; 44 }
本文为博主原创文章,转载请注明出处。