矩阵快速幂加速递推适用于求线性递推数列的值,例如本题经典的递推题,但发现数据范围n太大,常规方法o(n)会超时,这时候就要用到矩阵快速幂。此题的递推式如下,A是一个2*2的矩阵
很容易计算出A的个位置的值
我们要计算第n位的值,只需要用矩阵快速幂计算矩阵A的n-2次方,就能得出答案:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,p,q,a1,a2;
int a[4][4];
int b[4][4];
int b1[4][4];
void jzc(int c[4][4],int d[4][4])
{
//c*d
memset(b1,0,sizeof(b1));
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
for(int k=0;k<2;k++)
{
b1[i][j]+=c[i][k]*d[k][j];
b1[i][j]%=m;
}
}
}
}
signed main()
{
cin>>p>>q>>a1>>a2>>n>>m;
a[0][0]=p;
a[0][1]=1;
a[1][0]=q;
a[1][1]=0;
b[0][0]=1;
b[1][1]=1;
if(n==1)
{
cout<<a1%m<<endl;
return 0;
}
if(n==2)
{
cout<<a2%m<<endl;
return 0;
}
n-=2;
//快速幂
while(n)
{
if(n&1)
{
jzc(b,a);
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
b[i][j]=b1[i][j];
}
}
}
jzc(a,a);
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
a[i][j]=b1[i][j];
}
}
n>>=1;
}
a1%=m;
a2%=m;
int h=((a2*b[0][0])%m+(a1*b[1][0])%m)%m;
cout<<h<<endl;
}