POJ3070 Fibonacci(矩阵快速幂加速递推)【模板题】

题目链接:传送门

题目大意:

  求斐波那契数列第n项F(n)。

  (F(0) = 0, F(1) = 1, 0 ≤ n ≤ 109

思路:

  用矩阵乘法加速递推。

算法竞赛进阶指南的模板:

#include <iostream>
#include <cstring>

using namespace std;
const int MOD = 10000;

void mul(int f[2], int base[2][2]) {
    int c[2];
    memset(c, 0, sizeof c);
    for (int j = 0; j < 2; j++) {
        for (int k = 0; k < 2; k++) {
            c[j] = (c[j] + 1LL * f[k] * base[k][j]) % MOD;
        }
    }
    memcpy(f, c, sizeof c);
}
void mulself(int base[2][2]) {
    int c[2][2];
    memset(c, 0, sizeof c);
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            for (int k = 0; k < 2; k++)
                c[i][j] = (c[i][j] + 1LL*base[i][k]*base[k][j]) % MOD;
    memcpy(a, c, sizeof c);
}

int main()
{
    int n;
    while (cin >> n && n != -1) {
        int f[2] = {0, 1};
        int base[2][2] = {{0, 1}, {1, 1}};
        for (; n; n >>= 1) {
            if (n & 1) mul(f, base);
            mulself(base);
        }
        cout << f[0] << endl;
    }
    return 0;
}
View Code

蒟蒻的模板:

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;
typedef long long ll;
const int MOD = 1e4;
const int MAXN = 2;
struct Matrix{
    int mat[MAXN][MAXN];
    Matrix operator * (Matrix const& b) const {
        Matrix res;
        memset(res.mat, 0, sizeof res.mat);
        for (int i = 0; i < MAXN; i++)
            for (int j = 0; j < MAXN; j++)
                for (int k = 0; k < MAXN; k++)
                    res.mat[i][j] = (res.mat[i][j] + this->mat[i][k] * b.mat[k][j])%MOD;
        return res;
    }
}base, F0, FN;
Matrix fpow(Matrix base, ll n) {
    Matrix res;
    memset(res.mat, 0, sizeof res.mat);
    for (int i = 0; i < MAXN; i++)
        res.mat[i][i] = 1;
    while (n) {
        if (n&1) res = res*base;
        base = base * base;
        n >>= 1;
    }
    return res;
}
void init()
{
    base.mat[0][0] = 0; base.mat[0][1] = 1;
    base.mat[1][0] = 1; base.mat[1][1] = 1;
    memset(F0.mat, 0, sizeof F0.mat);
    F0.mat[0][0] = 1; F0.mat[0][1] = 1;
}

int main()
{
    int N;
    while (cin >> N) {
        if (N == -1)
            break;
        init();
        FN = fpow(base, N);
        cout << FN.mat[0][1] << endl;
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/Lubixiaosi-Zhaocao/p/9955571.html
今日推荐