话说某个幸运的小伙伴X拿到了kevin女神送的蛋糕,然而他的吃法非常奇特,他独创了两种吃蛋糕的办法:一、一次吃一整个蛋糕;二、一次吃k个蛋糕。
那么,当蛋糕数量为x1到x2之间时,一共能有几种不同的吃法呢?
由于答案很大,输出结果mod 1000000007的值
Input
第一行有两个正整数t,k(1<=t,k<=100000) ,其中t表示数据的组数。
接下来t行,每行两个数x1, x2(1<=x1<=x2<=100000)。
Output
共t行,每行一个正整数x,表示蛋糕数量在x1-x2之间时,一共能有几种不同的吃法,结果对(10^9+7)取模
Sample Input
3 2
1 3
2 3
4 4
Sample Output
6
5
5
Hint
样例中,k=2
我们标记吃法1为A,吃法2为B
当蛋糕数为1时,共1种吃法 即为A
当蛋糕数为2时,共2种,分别为 AA,B
当蛋糕数为3时,共3种,分别为 AAA,AB,BA
当蛋糕数为4时,共5种,分别为 AAAA, AAB,ABA,BAA,BB
这是一道简单的dp,但是取模和k=1这两个地方坑了我很久……
前缀和取模之后,sum[x2]可能比sum[x1-1]小,减出来就可能是负数
还有一个就是k=1的时候为什么不是永远只有一种吃法?一开始还想着说k=1特殊考虑了,结果就wa在k=1上
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
using namespace std;
typedef long long ll;
#define mod (int)(1e9+7)
int dp[100005];
int sum[100005];
int main()
{
int T,k;
scanf("%d%d",&T,&k);
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));
for(int i=1;i<=k-1;i++)
dp[i]=1;
dp[k]=2;
for(int i=k+1;i<=100000;i++)
dp[i]=(dp[i-1]%mod+dp[i-k]%mod)%mod;
for(int i=1;i<=100000;i++)
sum[i]=(sum[i-1]%mod+dp[i]%mod)%mod;
while(T--)
{
int x1,x2;
int ans=0;
scanf("%d%d",&x1,&x2);
ans=(sum[x2]-sum[x1-1])%mod;
if(ans<0) ans+=mod;
printf("%d\n",ans);
}
return 0;
}