大意
设
f
[
i
]
=
f
[
i
−
2
]
+
f
[
i
−
1
]
+
n
+
1
f[i]=f[i-2]+f[i-1]+n+1
f[i]=f[i−2]+f[i−1]+n+1
若
f
[
1
]
=
f
[
2
]
=
1
f[1]=f[2]=1
f[1]=f[2]=1求
f
[
n
]
m
o
d
9973
f[n]\ mod\ 9973
f[n] mod 9973
思路
考虑矩阵乘法加速递推
观察发现,这简直就是一个矩阵乘法板子,我们从这个方向想即可
首先因为有四个系数,所以我们建立一个 4 × 4 4\times 4 4×4的矩阵,然后去想每个数需要变成几就非常容易想到中间矩阵了
f
[
i
−
2
]
→
f
[
i
−
1
]
=
1
f[i-2]→f[i-1]=1
f[i−2]→f[i−1]=1
f
[
i
−
1
]
→
f
[
i
]
f[i-1]→f[i]
f[i−1]→f[i]
i
→
i
+
1
i→i+1
i→i+1
1
→
1
1→1
1→1
这样,所有四个系数的转移都想好了,现在只需按这个规则转移即可,如图
代码
#include<cstdio>
#include<cstring>
#define ymw 9973
using namespace std;int n;
struct node{int a[4][4],r,c;};
inline node mul(node x,node y)//矩阵乘法
{
node z;
memset(&z,0,sizeof(z));
for(register int i=0;i<x.r;i++)
for(register int j=0;j<y.c;j++)
for(register int k=0;k<x.c;k++)
z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j])%ymw;
z.r=x.r;z.c=y.c;
return z;
}
inline int ksm(register int y)
{
node x,ans;
memset(&x,0,sizeof(x));
memset(&ans,0,sizeof(ans));
x.r=x.c=ans.r=ans.c=4;
x.a[1][0]=1;
x.a[0][1]=x.a[1][1]=x.a[2][1]=x.a[3][1]=1;
x.a[2][2]=x.a[3][2]=1;
x.a[3][3]=1;
ans.a[0][0]=ans.a[0][1]=ans.a[0][3]=1;
ans.a[0][2]=3;//注意,初始是从第三个矩阵开始算
while(y)
{
if(y&1) ans=mul(ans,x);
x=mul(x,x);
y>>=1;
}
return ans.a[0][0];
}
signed main()
{
scanf("%d",&n);
printf("%d",ksm(n-1));
}