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

时间:2023-07-14 11:20:51

题目链接:传送门

题目大意:

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

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

思路:

  用矩阵乘法加速递推。

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

#include <iostream>
#include <cstring> using namespace std;
const int MOD = ; void mul(int f[], int base[][]) {
int c[];
memset(c, , sizeof c);
for (int j = ; j < ; j++) {
for (int k = ; k < ; k++) {
c[j] = (c[j] + 1LL * f[k] * base[k][j]) % MOD;
}
}
memcpy(f, c, sizeof c);
}
void mulself(int base[][]) {
int c[][];
memset(c, , sizeof c);
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
for (int k = ; k < ; 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 != -) {
int f[] = {, };
int base[][] = {{, }, {, }};
for (; n; n >>= ) {
if (n & ) mul(f, base);
mulself(base);
}
cout << f[] << endl;
}
return ;
}

蒟蒻的模板:

#include <cstdio>
#include <iostream>
#include <cstring> using namespace std;
typedef long long ll;
const int MOD = 1e4;
const int MAXN = ;
struct Matrix{
int mat[MAXN][MAXN];
Matrix operator * (Matrix const& b) const {
Matrix res;
memset(res.mat, , sizeof res.mat);
for (int i = ; i < MAXN; i++)
for (int j = ; j < MAXN; j++)
for (int k = ; 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, , sizeof res.mat);
for (int i = ; i < MAXN; i++)
res.mat[i][i] = ;
while (n) {
if (n&) res = res*base;
base = base * base;
n >>= ;
}
return res;
}
void init()
{
base.mat[][] = ; base.mat[][] = ;
base.mat[][] = ; base.mat[][] = ;
memset(F0.mat, , sizeof F0.mat);
F0.mat[][] = ; F0.mat[][] = ;
} int main()
{
int N;
while (cin >> N) {
if (N == -)
break;
init();
FN = fpow(base, N);
cout << FN.mat[][] << endl;
}
return ;
}