该题目需要注意的是会出现两个前缀和相减出现负数的情况,如下:
所以需要在两前缀和相减取模之前先加上一个M
题目描述
Everybody knows Fibonacci numbers, now we are talking about the Tribonacci numbers:
T[0] = T[1] = T[2] = 1;
T[n] = T[n - 1] + T[n - 2] + T[n - 3] (n >= 3)
Given a and b, you are asked to calculate the sum from the ath Fibonacci number to the bth Fibonacci number, mod 1,000,000,007, that is (T[a] + T[a + 1] + ... + T[b]) % 1,000,000,007.
输入
There are multiple cases (no more than 100).
Each case contain two non-negative integers a b(a <= b and a, b < 1,000,000,000)
输出
For each case, output the sum % 1,000,000,007.
样例输入 Copy
0 2 0 5
以下为AC代码
#include<bits/stdc++.h>
using namespace std;
int a1[5][5];
int ans[5][5];
const int M=1000000007;
void matrixmul(int m1[][5],int m2[][5],int col)
{
int b[5][5];
memset(b,0,sizeof(b));
for(int i=1;i<=4;i++)
for(int j=1;j<=col;j++)
for(int p=1;p<=4;p++){
b[i][j]+=((long long)m1[i][p]*(long long)m2[p][j])%M;
b[i][j]%=M;
}
for(int i=1;i<=4;i++)
for(int j=1;j<=col;j++)m2[i][j]=b[i][j]%M;
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int a,b,sum1,sum2;
while(cin>>a>>b){
int a2[5][5]={
0,0,0,0,0,
0,1,1,1,1,
0,0,1,1,1,
0,0,1,0,0,
0,0,0,1,0
};
a1[1][1]=3,a1[2][1]=1,a1[3][1]=1,a1[4][1]=1;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)ans[i][j]=(i==j);
int b1=b;
if(b<=2){
cout<<b-a+1<<'\n';
continue;
}
b-=(a-1);
a-=3;
if(a<=0){
switch(a){
case -3:sum1=0;break;
case -2:sum1=1;break;
case -1:sum1=2;break;
case 0:sum1=3;break;
}
b=b1-2;
goto EXIT;
}
while(a){
if(a%2){
a--;
matrixmul(a2,ans,4);
}else{
a/=2;
matrixmul(a2,a2,4);
}
}
matrixmul(ans,a1,1);
sum1=a1[1][1]%M;
EXIT:
int b2[5][5]={
0,0,0,0,0,
0,1,1,1,1,
0,0,1,1,1,
0,0,1,0,0,
0,0,0,1,0
};
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)ans[i][j]=(i==j);
while(b){
if(b%2){
b--;
matrixmul(b2,ans,4);
}else{
b/=2;
matrixmul(b2,b2,4);
}
}
matrixmul(ans,a1,1);
sum2=a1[1][1]%M;
cout<<(sum2+M-sum1)%M<<'\n';//加上M以避免出现负数情况
}
return 0;
}
样例输出 Copy
3 20