• 「题解」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;
    }
    
  • 相关阅读:
    BlockingQueue 原理 分析
    java引用 强引用,软引用,弱引用
    actomic cas无锁操作。
    MongoDB库设计原则及实践
    spring事物传播机制 事物隔离级别
    Hive UDAF介绍与开发
    [技术学习]js接口继承
    [技术学习]js继承
    [技术学习]正则表达式分析
    [技术学习]js正则表达式汇总
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13835072.html
Copyright © 2020-2023  润新知