首页 > 代码库 > UVA10299- Modular Fibonacci(斐波那契数列+矩阵快速幂)

UVA10299- Modular Fibonacci(斐波那契数列+矩阵快速幂)

题目链接


题意:给出n和m,求出f(n) % m, f(x)为斐波那契数列。

思路:因为n挺大的,如果直接利用公式计算很有可能会TLE,所以利用矩阵快速幂求解,|(1, 1), (1, 0)| * |f(n - 1), f(n - 2)| = |f(n), f(n - 1)|,所以求f(n)相当于|f(1), f(0)|乘上n - 1次的|(1, 1), (1, 0)|。

代码:

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

typedef long long ll;
using namespace std;
ll n, p, k;
int m;

struct mat{
    ll s[2][2];
    mat(ll a = 0, ll b = 0, ll c = 0, ll d = 0) {
        s[0][0] = a; 
        s[0][1] = b; 
        s[1][0] = c; 
        s[1][1] = d; 
    }
}c(1, 1, 1, 0), tmp(1, 0, 0, 1);

mat operator * (const mat& a, const mat& b) {
    mat Mat;
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            Mat.s[i][j] = (a.s[i][0] * b.s[0][j] + a.s[i][1] * b.s[1][j]) % p;
    return Mat; 
}

mat pow_mod(ll k) {
    if (k == 0)
        return tmp;
    else if (k == 1)
        return c;
    mat a = pow_mod(k / 2);
    a = a * a;
    if (k % 2)
        a = a * c;
    return a;
}

int main() {
    while (scanf("%lld%d", &n, &m) != EOF) {
        p = pow(2, m); 
        if (n) {
            mat ans = pow_mod(n - 1); 
            k = ans.s[0][0];
        }  
        else
            k = 0;
        printf("%lld\n", k);
    } 
    return 0;
}


UVA10299- Modular Fibonacci(斐波那契数列+矩阵快速幂)