斐波那契(矩阵快速幂)
今天随便看了看矩阵的相关内容,顺势学习了一下矩阵构造和矩阵快速幂,然后又顺道写了这个入门题。
斐波那契数列,即,就这么一个数列,显然可以直接递推求解,时间复杂度,似乎没什么问题。
然后就遇到了这个,的取值范围最大是的这么一个题,线性显然不能满足时间限制,然后就需要用矩阵快速幂求解了。
用表示一个的矩阵,推道依然按照递推式,我们发现,显然就是中将第二项前移做为第一项,第一项和原第二项的和作为新的第二项(递推),即相当于每次乘以了一个的矩阵,我们可以求出这个矩阵是
我们记这个矩阵为
也就是说,,相应的,,依次类推,而我们需要求的实际上就是第一项,也就是说,只要求得了,就相当于求得了,于是问题就转换为了矩阵快速幂。
#include <bits/stdc++.h>
using namespace std;
int n;
const int mod = 10000;
struct p{
int arr[3][3];
p(){
}
p(int a[3][3]){
for (int i = 1; i <= 2; i++){
for (int j = 1; j <= 2; j++){
arr[i][j] = a[i][j];
}
}
}
p operator * (const p& a){
p temp;
temp.arr[1][1] = this->arr[1][1] * a.arr[1][1] + this->arr[1][2] * a.arr[2][1];
temp.arr[1][2] = this->arr[1][1] * a.arr[1][2] + this->arr[1][2] * a.arr[2][2];
temp.arr[2][1] = this->arr[2][1] * a.arr[1][1] + this->arr[2][2] * a.arr[2][1];
temp.arr[2][2] = this->arr[2][1] * a.arr[1][2] + this->arr[2][2] * a.arr[2][2];
return temp;
}
void MOD(){
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
this->arr[i][j] %= mod;
}
};
int te[3][3];
int one[3][3];
p qpow(p temp, int n){
p ans = p(one);
ans.MOD();
while (n){
if (n & 1){
ans = ans * temp;
ans.MOD();
}
n >>= 1;
temp = temp * temp;
temp.MOD();
}
ans.MOD();
return ans;
}
int main() {
ios::sync_with_stdio(0);
te[1][1] = 0, te[1][2] = te[2][1] = te[2][2] = 1;
one[1][1] = one[2][2] = 1;
one[1][2] = one[2][1] = 0;
while (cin >> n && (~n)){
p ans = qpow(p(te), n);
cout << ans.arr[2][1] << "\n";
}
return 0;
}
本文来自博客园,作者:correct,转载请注明原文链接:https://www.cnblogs.com/correct/p/12861905.html

浙公网安备 33010602011771号