JDOJ-1119: Fibonacci sequence

题目链接: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;
}

猜你喜欢

转载自www.cnblogs.com/oi-forever/p/8926627.html