题意: 求一个下标等差的类似斐波那契数列的和.
用一个矩阵来表示求和的过程就好了:
[Si−1f4i−1f4i−2f4i−3f4i−4]×⎡⎣⎢⎢⎢⎢⎢⎢1100005300032000210001100⎤⎦⎥⎥⎥⎥⎥⎥=[Sif4i+3f4i+2f4i+1f4i]
#include <bits/stdc++.h>
using namespace std;
#define maxn 1005
#define mod 1000000007
struct m {
long long a[5][5];
m operator * (m gg) {
m ans;
memset (ans.a, 0, sizeof ans.a);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
for (int l = 0; l < 5; l++) {
ans.a[i][j] += a[i][l]*gg.a[l][j];
ans.a[i][j] %= mod;
}
}
}
return ans;
}
void show () {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++)
cout << a[i][j] << " ";
cout << endl;
}
}
};
m qpow (m a, long long kk) {
m ans;
int i, j;
for(i = 0; i < 5; ++i)
for(j = 0; j < 5; ++j)
ans.a[i][j] = (i == j ? 1 : 0);
for(; kk; kk >>= 1) {
if(kk&1) ans = ans*a;
a = a*a;
}
return ans;
}
long long solve (long long n) {
m a;
long long xx[5][5] = {{1,0,0,0,0}, {1,5,3,2,1}, {0,3,2,1,1}, {0,0,0,0,0}, {0,0,0,0,0}};
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
a.a[i][j] = xx[i][j];
}
}
a = qpow (a, n);
long long ans = 2*a.a[1][0] + a.a[2][0] + a.a[3][0];
return ans % mod;
}
int main () {
int t;
scanf ("%d", &t);
long long l, r;
while (t--) {
scanf ("%lld%lld", &l, &r);
long long ans = solve (r)-solve (l-1);
printf ("%lld\n", (ans%mod+mod)%mod);
}
return 0;
}