版权声明:随意转载 https://blog.csdn.net/nuiniu/article/details/81151754
建两个数组a[MAX],b[MAX],a[i]用来存走到i位置的种类数,b[i]则用来存前i个所有位置种类的和。再来,就是找规律了。
k=1时(由于我的i时从0开始的,所以i为第i+1步!!!同下),a[0]=2,a[1]=3,a[2]=5,a[3]=8,a[4]=13,a[5]=21....
=>a[i]=a[i-1]+a[i-2] (i>=2);
k=2时:a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=6,a[5]=9,....a[i]=a[i-1]+a[i-3] (i>=3);
k=3时: a[0]=1,a[1]=1;a[2]=2,a[3]=3,a[4]=4,a[5]=5,a[6]=5,a[7]=7,a[8]=10... a[i]=a[i-1]+a[i-4] (i>=4);
k=4时: 1 1 1 2 3 4 5 6 8 11 a[i]=a[i-1]+a[i-5] (i>=5);
综上所述,a[i]=a[i-1]+a[i-k-1] (1<=k<=100000,i>=k+1);
代码:
#include<stdio.h>
const int mod=1000000000+7;
int main()
{
int q,k,r,l,i;
int a[100005],b[100005];
scanf("%d%d",&q,&k);
for(i=0;i<k-1;i++)
{
a[i]=1;
if(i==0) b[i]=a[i];
else b[i]=b[i-1]+a[i-1];
}
a[i]=2;
if(i==0) b[i]=a[i-1];
else b[i]=b[i-1]+a[i-1];
a[++i]=3;
b[i]=b[i-1]+a[i-1];
i++;
for(;i<100000;i++)
{
a[i]=a[i-1]%mod+a[i-k-1]%mod;
a[i]=a[i]%mod;
b[i]=b[i-1]+a[i-1]%mod;
b[i]=b[i]%mod;
}
b[i]=b[i-1]+a[i-1]%mod;
b[i]=b[i]%mod;
// for(i=0;i<=100;i++) printf("%d ",a[i]);
// printf("\n");
// for(i=0;i<=100;i++) printf("%d ",b[i]);
for(int i=0;i<q;i++)
{
int ans=0;
scanf("%d%d",&l,&r);
ans=(b[r]-b[l-1]+mod)%mod;
printf("%d\n",ans);
}
return 0;
}
嗯,结果输出记得是ans=(b[r]-b[l-1]+mod),以免b[r]取模之后比b[l-1]小。。。(我就卡在这里好久)。