POJ3070 Fibonacci(矩阵快速幂加速递推)【模板题】
题目链接:传送门
题目大意:
求斐波那契数列第n项F(n)。
(F(0) = 0, F(1) = 1, 0 ≤ n ≤ 109)
思路:
用矩阵乘法加速递推。
算法竞赛进阶指南的模板:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }
蒟蒻的模板:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }