Description
Data Constraint
Solution
这一看就知道是一道矩阵乘法的题。显然
Fn=∑ni=0fi∗fn−i=∑ni=0fi∗(fn−i−1+fn−i−2)=∑ni=0fi∗fn−i−1+∑ni=0fi∗fn−i−2=Fn−1+Fn−2+fn∗f0=Fn−1+Fn−2+fn
这样,我们就可以推出矩阵啦,先设个初始状态数组
a=Fi,Fi−1,fi+1,fi,sum
sum表示
∑i−1j=0Fj
,根据这个推一下矩阵,用矩阵快速幂O(
logN∗53
)解决。
代码
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const ll maxn=998244353;
struct code{
ll a[5][5];
}p,b,z;
ll f[5],g[5],n,i,j,t,k,l;
code c(code x,code y){
memset(z.a,0,sizeof(z.a));
for (i=0;i<5;i++)
for (j=0;j<5;j++)
for (k=0;k<5;k++)
z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%maxn)%maxn;
return z;
}
code mi(ll x){
if (x==1) return p;
code t=mi(x/2);
if (x%2) return c(c(t,t),p);return c(t,t);
}
int main(){
scanf("%lld",&n);
f[0]=2;f[1]=1;f[2]=2;f[3]=1;f[4]=1;
p.a[0][0]=p.a[0][1]=p.a[0][4]=p.a[1][0]=p.a[2][0]=p.a[2][2]=p.a[2][3]=p.a[3][2]=p.a[4][4]=1;
if (!n) printf("1\n");
else{
b=mi(n);
for (j=0;j<5;j++)
for (k=0;k<5;k++)
g[j]=(g[j]+f[k]*b.a[k][j]%maxn)%maxn;
printf("%lld\n",g[4]);
}
}