矩阵快速幂
处理何种问题:用于优化加速一些线性关系式,可将一些时间复杂度降至O(logn)。
(如果题目上出现 1e18 之类的数据范围,就可以往矩阵快速幂上想了)
性能:具体的时间复杂度为O(edge * edge * log n),edge为矩阵的阶数。
原理:矩阵乘法性质、快速幂。
实现步骤:以斐波那契数列为例
公式为: F[i] = F[i-1] + F[i-2],根据公式将此转化为矩阵公式

备注:需要进行 *、= 符号的重载,套用快速幂模板,但取模在 * 重载函数中。
输入样例解释:
99999999999999 //f(n)
输出样例解释:
626 //结果
--------------------------------------------------------------------
代码:
///此代码为求斐波那契数列矩阵快速幂,若要求其他矩阵快速幂注意更改标记 <--- 的行。
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
const long long mod=10000;/// <---
const int edge=2;/// <---
struct Matrix ///定义矩阵,重载*,=;
{
long long a[edge][edge];
Matrix()
{
memset(a,0,sizeof(a));///构造函数,初始化矩阵
}
Matrix operator *(const Matrix b) ///自定义矩阵乘法
{
Matrix temp;
for(int i=0; i<edge; ++i)
for(int j=0; j<edge; ++j)
for(int k=0; k<edge; ++k)
{
temp.a[i][j]+=a[i][k]*b.a[k][j];
temp.a[i][j]%=mod;///在此取模
}
return temp;
}
};
Matrix m_fpow(Matrix a,long long n)
{
Matrix Ans;
Ans.a[0][0]=Ans.a[1][1]=1;///初始化为单位矩阵 // <---
while(n!=0)///套用快速幂
{
if(n&1)
Ans=Ans*a;
n=n>>1;
a=a*a;
}
return Ans;
}
int main()
{
Matrix Ans,a,b;
long long n;
scanf("%lld",&n);
if(n==0)
printf("0\n");
else if(n==1)
printf("1\n");
else
{
a.a[0][0]=a.a[0][1]=a.a[1][0]=1;///初始化,不同的dp关系对应不同的矩阵 // <---
b.a[0][0]=b.a[1][0]=1; /// <---
Ans=m_fpow(a,n-2)*b;
printf("%lld\n",Ans.a[0][0]);
}
return 0;
}

浙公网安备 33010602011771号