1. 程式人生 > >快速冪 與矩陣快速冪

快速冪 與矩陣快速冪

/*快速冪*/
int qpow(int a, int b) {
    int ans = 1, base = a;
    while (b) {
        if (b & 1)
            ans *= base;
            base *= base;
            b >>= 1;
    }
    return ans;
}
/*矩陣快速冪*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int mod = 10000;
const int maxn = 35;
int N;
struct Matrix {
    int mat[maxn][maxn];
    int x, y;
    Matrix() {
        memset(mat, 0, sizeof(mat));
        for (int i = 1; i <= maxn - 5; i++) mat[i][i] = 1;
    }
};
inline void mat_mul(Matrix a, Matrix b, Matrix &c) {
    memset(c.mat, 0, sizeof(c.mat));
    c.x = a.x; c.y = b.y;
    for (int i = 1; i <= c.x; i++) {
        for (int j = 1; j <= c.y; j++) {
            for (int k = 1; k <= a.y; k++) {
                c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod;
                c.mat[i][j] %= mod;
            }
        }
    }
    return ;
}
inline void mat_pow(Matrix &a, int z) {
    Matrix ans, base = a;
    ans.x = a.x; ans.y = a.y;
    while (z) {
        if (z & 1 == 1) mat_mul(ans, base, ans);
        mat_mul(base, base, base);
        z >>= 1;
    }
    a = ans;
}
int main() {
    while (cin >> N) {
        switch (N) {
            case -1: return 0;
            case 0: cout << "0" << endl; continue;
            case 1: cout << "1" << endl; continue;
            case 2: cout << "1" << endl; continue;
        }
        Matrix A, B;
        A.x = 2; A.y = 2;
        A.mat[1][1] = 1; A.mat[1][2] = 1;
        A.mat[2][1] = 1; A.mat[2][2] = 0;
        B.x = 2; B.y = 1;
        B.mat[1][1] = 1; B.mat[2][1] = 1;
        mat_pow(A, N - 1);
        mat_mul(A, B, B);
        cout << B.mat[1][1] << endl;
    }
    return 0;
}