Problem Description
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.

Input
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)

Output
For each case, output the sum % 1,000,000,007.

 

输入样例

0 2
0 5

输出样例

3
20

构造带前缀和的矩阵,注意两个前缀和数相减求模时的计算
附ac代码
#include<bits/stdc++.h>
using namespace std;
const int N=4,mod=1e9+7;
int unit[N][N]={{1,1,1,1},{0,1,1,1},{0,1,0,0},{0,0,1,0}};
typedef long long ll;
struct matrix{
    ll ma[N][N];
};
matrix muti(matrix a,matrix b)
{
    matrix c;
    for(int i=0;i<N;++i)
      for(int j=0;j<N;++j)
      c.ma[i][j]=0;
    for(int i=0;i<N;++i)
      for(int j=0;j<N;++j)
       for(int z=0;z<N;++z)
    {    c.ma[i][j]+=(a.ma[i][z]%mod*(b.ma[z][j]%mod)%mod);
         c.ma[i][j]%=mod;
    }
    return c;
}
matrix pow_ma(matrix a,int k)
{
    if(k==1) return a;
    matrix s;
    s=pow_ma(muti(a,a),k/2);
    if(k%2) s=muti(s,a);
    return s;
}
int main()
{
    int a,b;
    int t[4]={1,1,1,3};
    while(scanf("%d%d",&a,&b)==2)
    {
        matrix ans,ans1,ans2;
        for(int i=0;i<N;++i)
          for(int j=0;j<N;++j)
          ans.ma[i][j]=unit[i][j];
        if(b<=2)
        {
            int sum=0;
            for(int i=a;i<=b;++i)
            sum+=t[i];
            printf("%d\n",sum);
            continue;
        }
        if(a<=3)
        {
            int s[4];
            s[0]=1;s[1]=2;s[2]=3;
            ans2=pow_ma(ans,b-2);
            ll sum=0;
            for(int i=0;i<N;++i)
            {sum+=(ans2.ma[0][i]%mod*t[N-1-i])%mod;
            sum%=mod;
            }
            if(a) printf("%lld\n",(sum+mod-s[a-1])%mod);
            else   printf("%lld\n",(sum)%mod);
        }//关于a,b的讨论可以用一个函数写返回值表示s[x],避免过多讨论
        else
        {
            ans1=pow_ma(ans,a-3);
            ans2=pow_ma(ans,b-2);
            ll sum1=0,sum2=0;
            for(int i=0;i<N;++i)
            {sum1+=(ans1.ma[0][i]%mod*t[N-1-i])%mod;
             sum2+=(ans2.ma[0][i]%mod*t[N-1-i])%mod;
             sum1%=mod;//对sum1,sum2的%处理
             sum2%=mod;
            }
            printf("%lld\n",(sum2+mod-sum1)%mod);//需要+mod在减防止出现负数
        }
    }
    return 0;
}

 

 posted on 2023-01-15 09:49  ruoye123456  阅读(169)  评论(0)    收藏  举报