矩阵快速幂求斐波那契数列
acwing题目链接https://www.acwing.com/problem/content/207/
题目描述
在斐波那契数列中,Fib0=0,Fib1=1,Fibn=Fibn−1+Fibn−2(n>1)。
给定整数n,求Fibnmod10000。
输入格式
输入包含多组测试用例。
每个测试用例占一行,包含一个整数n。
当输入用例n=-1时,表示输入终止,且该用例无需处理。
输出格式
每个测试用例输出一个整数表示结果。
每个结果占一行。
数据范围
0≤n≤2∗109
思路
矩阵的乘法可以加速数列的递推。这一题n特别大,单纯的递推会TLE。
如果我们找到某个转移矩阵,让其左乘数列的某个状态,可以推出下一个状态,那么想求第n个状态,不就成了乘n次转移矩阵的问题?结合快速幂,无非就是把数的幂次换成了矩阵呗
代码
#include <bits/stdc++.h>
using namespace std;
const int mod = 10000;
const int N = 2;
int n;
vector<vector<int>> a(N, vector<int>(N, 0)), f(1, vector<int>(N, 0));
void init()
{
a[0][0] = 0, a[0][1] = 1;
a[1][0] = 1, a[1][1] = 1;
f[0][0] = 0, f[0][1] = 1;
}
vector<vector<int>> mul(vector<vector<int>> &A, vector<vector<int>> &B)
{
vector<vector<int>> C (A.size(), vector<int>(B[0].size(), 0));
for(int i = 0; i < A.size(); i ++)
for(int j = 0; j <B[0].size(); j ++)
for(int k = 0; k < A[0].size(); k ++)
C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % mod;
return C;
}
int main()
{
while(cin >> n, n != -1)
{
init();
while(n)
{
if(n & 1) f = mul(f, a);
a = mul(a, a);
n >>= 1;
}
cout << f[0][0] <<endl;
}
}