计蒜客习题:Fib数列问题之二


问题描述

用 fib(n) 表示斐波那契数列的第 n项,现在要求你求 fib(n) mod m。fib(1)=1,fib(2)=1。
输入格式
输入 2 个整数 n(1≤n≤10^18 ),m(2≤m≤100000000)。
输出格式
输出 fib(n) 对 m 取模的值。
样例输入
100000000 100000000
样例输出
60546875


AC代码

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
int n=2; // 所有矩阵都是 n * n 的矩阵
struct matrix {
   ll a[100][100];
};
matrix matrix_mul(matrix A, matrix B, int mod) {
    // 2 个矩阵相乘
    matrix C;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            C.a[i][j] = 0;
            for (int k = 1; k <= n; ++k) {
                C.a[i][j] += A.a[i][k] * B.a[k][j] % mod;
                C.a[i][j] %= mod;
            }
        }
    }
    return C;
}
matrix unit() {
    // 返回一个单位矩阵
    matrix res;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            if (i == j) {
                res.a[i][j] = 1;
            } else {
                res.a[i][j] = 0;
            }
        }
    }
    return res;
}
matrix matrix_pow(matrix A, long long n, int mod) {
    // 快速求矩阵 A 的 n 次方
    matrix res = unit(), temp = A;
    for (; n; n /= 2) {
        if (n & 1) {
            res = matrix_mul(res, temp, mod);
            //cout<<res.a[1][1]<<" "<<res.a[1][2]<<endl<<res.a[2][1]<<" "<<res.a[2][2]<<endl;
        }
        temp = matrix_mul(temp, temp, mod);
    }
    return res;
}
matrix mul(matrix a,matrix b,int mod)
{
    matrix C;
    for (int i = 1; i <= 2; ++i) {
        for (int j = 1; j <= 2; ++j) {
            C.a[i][j] = 0;
            for (int k = 1; k <= 1; ++k) {
                C.a[i][j] += a.a[i][k] * b.a[k][j];
                C.a[i][j]%=mod;
            }
        }
    }
    return C;
}
ll fib(ll n,ll mod)
{
    matrix res;
    res.a[1][1]=1;
    res.a[1][2]=1;
    res.a[2][1]=1;
    res.a[2][2]=0;
    res=matrix_pow(res,n-1,mod);
    matrix rr;
    rr.a[1][1]=1;
    rr.a[2][1]=1;
    rr=mul(rr,res,mod);
    cout<<rr.a[2][1];
}
int main()
{
    ll m,n;
    cin>>m>>n;
    fib(m,n);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liukairui/article/details/80032754