题目链接:https://neooj.com:8082/oldoj/problem.php?id=1119
题目大意:求第x到第y项斐波拉契和 mod10000.x, y <= int
总结
- 主要是构造矩阵
- 矩阵元素为前缀和 si 表示 a1 + a2 +.....ai
ai ai+1 ai+2
ai+1 0 1 0
ai+2 0 0 1
ai+3 -1 0 2
写出对应矩阵
0 0 -1
1 0 0
0 1 2
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 10000;
int T, n, m;
ll b[5], a[5][5], C[5], e[5][5];
ll ans1, ans2;
void clen() {
b[1] = 1, b[2] = 2, b[3] = 4;
a[1][1] = 0; a[1][2] = 0; a[1][3] = -1;
a[2][1] = 1; a[2][2] = 0; a[2][3] = 0;
a[3][1] = 0; a[3][2] = 1; a[3][3] = 2;
}
void solve() {
memset(C, 0, sizeof C);
for (int i = 1; i <= 3; ++i) {
for (int j = 1; j <= 3; ++j) {
C[i] = C[i] + b[j] * a[j][i];
}
}
for (int i = 1; i <= 3; ++i) b[i] = C[i] % mod;
}
void ck() {
memset(e, 0, sizeof e);
for (int i = 1; i <= 3; ++i) {
for (int j = 1; j <= 3; ++j) {
for (int k = 1; k <= 3; ++k) {
e[i][j] = e[i][j] + a[i][k] * a[k][j];
}
}
}
for (int i = 1; i <= 3; ++i) {
for (int j = 1; j <= 3; ++j) {
a[i][j] = e[i][j] % mod;
}
}
}
ll work(int c) {
ll res = 0;
if(c == -1) return 0;
while(c) {
if(c & 1) {
solve();
} c >>= 1; ck();
} res = b[1]; return res % mod;
}
int main() {
scanf("%d", &T);
while(T--) {
clen();
scanf("%d%d", &n, &m);
int x = n - 2, y = m - 1;
ans1 = work(x);
clen();
ans2 = work(y);
printf("%lld\n", ((ans2 - ans1) % mod + mod) % mod);
}
return 0;
}