Bzoj4402 Claris的剑

Time Limit: 10 Sec  Memory Limit: 256 MB
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
",ans);
43     return 0;
44 }
原文地址:https://www.cnblogs.com/SilverNebula/p/6909837.html