「题解」hdu 4549 M斐波那契数列

题目

hdu 4549 M斐波那契数列

(f_0=a)

(f_1=b)

(f_i=f_{i-1} imes f_{i-2},i>1)

(f_n)

思路

(f_0=a,f_1=b,f_2=ab,f_3=ab^2,f_4=a^2b^3,f_5=a^3b^5)

发现指数都是斐波那契数列中相邻的两个数,指数可以用矩阵快速幂加速递推去求。

因为模数为 (1e9+7) 是个质数,可以用费马小定理降幂。

Code

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>

const int mod = 1000000007;
int a, b, n;
struct Matrix {
    int g[3][3];
    Matrix() { memset(g, 0, sizeof g); }
    void one() { g[1][1] = g[2][2] = 1; }
    friend Matrix operator * (Matrix m1, Matrix m2) {
        Matrix ans;
        for (int k = 1; k <= 2; ++k) {
            for (int i = 1; i <= 2; ++i) {
                for (int j = 1; j <= 2; ++j) {
                    ans.g[i][j] = (ans.g[i][j] + (1ll * m1.g[i][k] * m2.g[k][j] % (mod - 1))) % (mod - 1);
                }
            }
        }
        return ans;
    }
}tra, res, f;

Matrix qpow(Matrix a, int b) {
    Matrix ans, base = a;
    ans.one();
    while (b) {
        if (b & 1) ans = ans * base;
        base = base * base;
        b >>= 1;
    }
    return ans;
}

int qp(int a, int b) {
    int ans = 1, base = a;
    while (b) {
        if (b & 1) ans = 1ll * ans * base % mod;
        base = 1ll * base * base % mod;
        b >>= 1;
    }
    return ans;
}

int main() {
    while (scanf("%d %d %d", &a, &b, &n) != EOF) {
        if (n == 0) {
            printf("%d
", a);
            continue;
        }
        tra.g[1][1] = tra.g[1][2] = tra.g[2][1] = 1, tra.g[2][2] = 0;
        f.g[1][1] = 1, f.g[2][1] = res.g[1][1] = res.g[2][1] = 0;
        tra = qpow(tra, n - 1);
        for (int k = 1; k <= 2; ++k) {
            for (int i = 1; i <= 2; ++i) {
                for (int j = 1; j <= 1; ++j) {
                    res.g[i][j] = (res.g[i][j] + (1ll * tra.g[i][k] * f.g[k][j] % (mod - 1))) % (mod - 1);
                }
            }
        }
        printf("%lld
", (1ll * qp(a, res.g[2][1]) * qp(b, res.g[1][1])) % mod);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13835072.html