--正文
矩阵快速幂,难点在如何构造(注意Sum(r) = Sum(r-1) + T(r))
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MOD 1000000007 typedef long long LL; typedef struct { LL M[4][4]; } Matrix; Matrix Ans,Base; long long answer[5] = {1,2,3,6,11}; long long l,r; Matrix multi(Matrix a,Matrix b){ Matrix Tmp; int i,j,k; for (i=0;i<4;i++){ for (j=0;j<4;j++){ Tmp.M[i][j] = 0; for (k=0;k<4;k++){ Tmp.M[i][j] = (Tmp.M[i][j] + a.M[i][k] * b.M[k][j]) % MOD; } } } return Tmp; } LL Fast_Mod(LL n){ Base.M[0][0] = 1; Base.M[0][1] = 1; Base.M[0][2] = 1; Base.M[0][3] = 0; Base.M[1][0] = 1; Base.M[1][1] = 0; Base.M[1][2] = 0; Base.M[1][3] = 0; Base.M[2][0] = 0; Base.M[2][1] = 1; Base.M[2][2] = 0; Base.M[2][3] = 0; Base.M[3][0] = 1; Base.M[3][1] = 0; Base.M[3][2] = 0; Base.M[3][3] = 1; Ans.M[0][0] = 1; Ans.M[0][1] = 0; Ans.M[0][2] = 0; Ans.M[0][3] = 0; Ans.M[1][0] = 0; Ans.M[1][1] = 1; Ans.M[1][2] = 0; Ans.M[1][3] = 0; Ans.M[2][0] = 0; Ans.M[2][1] = 0; Ans.M[2][2] = 1; Ans.M[2][3] = 0; Ans.M[3][0] = 0; Ans.M[3][1] = 0; Ans.M[3][2] = 0; Ans.M[3][3] = 1; while (n){ if (n&1) Ans = multi(Ans,Base); Base = multi(Base,Base); n = n >> 1; } return (Ans.M[3][0] + Ans.M[3][1] + Ans.M[3][2] + 2*Ans.M[3][3]) % MOD; } int main(){ while (scanf("%lld %lld",&l,&r) != EOF){ LL ansa,ansb; if (l == 0) { ansa = 0; } else if (l < 6) { ansa = answer[l-1]; } else ansa = Fast_Mod(l-2); if (r < 5){ ansb = answer[r]; } else ansb = Fast_Mod(r-1); //printf("%lld %lld ",ansa,ansb); printf("%lld ",(ansb+MOD-ansa)%MOD); } return 0; }