[Template] Matrix fast power
Topic link: [Template] Matrix fast power
Problem solving ideas
This is a template question, the question is very clear that this is a quick exponent .
In fact, it is similar to fast power, but there is one thing to pay attention to
fast power ans ansa n s is generally assigned as1 11. The purpose is to makeans ansa n s can get the value directly in the first operation.
But what should we use to achieve the goal in matrix multiplication?
The easiest way is to performans ans for thefirst timeIn the calculation of a n s , it is judged and then assigned.
But there is another idea: after
a matrix is multiplied by another matrix, the original matrix can be obtained. What will this matrix be?
Such as:
∣ 1 2 3 4 ∣ \begin{vmatrix}1 & 2\\3 &4\end{vmatrix}∣∣∣∣1324∣∣∣∣
We go back and get:
∣ 1 0 0 1 ∣ \begin{vmatrix}1 & 0\\0 &1\end{vmatrix}∣∣∣∣1001∣∣∣∣
Verify that it is correct.
In this way, quick power is enough
code
#include<iostream>
#include<cstdio>
#include<cstring>
#define lzh using
#define ak namespace
#define ioi std
lzh ak ioi;
const int mod=9973;
int n;
int a[4][4];
int ans[4][4];
int t[4][4];
void add()
{
memset(t,0,sizeof(t));
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
for(int k=1;k<=3;k++)
t[i][j]=(t[i][j]+ans[i][k]*a[k][j])%mod;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
ans[i][j]=t[i][j];
}
void cf()
{
memset(t,0,sizeof(t));
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
for(int k=1;k<=3;k++)
t[i][j]=(t[i][j]+a[i][k]*a[k][j])%mod;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
a[i][j]=t[i][j];
}
void ksm(int b)
{
for(int i=1;i<=3;i++)
ans[i][i]=1;
while(b)
{
if(b&1)
add();
cf();
b>>=1;
}
}
int main()
{
cin>>n;
if(n<=2)
{
cout<<1<<endl;
return 0;
}
a[1][1]=0,a[1][2]=1,a[1][3]=0;
a[2][1]=1,a[2][2]=1,a[2][3]=0;
a[3][1]=0,a[3][2]=1,a[3][3]=1;
ksm(n-2);
cout<<(ans[1][2]+ans[2][2]+ans[3][2])%mod<<endl;
}