传送门
来源:牛客网
qn是个特别可爱的小哥哥,qy是个特别好的小姐姐,他们两个是一对好朋友 [ cp (划掉~)
又是一年嘤花烂漫时,小qn于是就邀请了qy去嘤花盛开的地方去玩。当qy和qn来到了田野里时,qy惊奇的发现,嘤花花瓣以肉眼可见的速度从树上长了出来。
仔细看看的话,花瓣实际上是以一定规律长出来的,而且,每次张成新的花瓣的时候,上一次的花瓣就会都落到地上,而且不会消失。
花瓣生长的规律是,当次数大于等于2时,第i次长出来的花瓣个数和上一次张出来的花瓣个数的差是斐波那契数列的第i-1项。初始的时候地上没有花瓣,树上的花瓣个数为1,第一次生长的花瓣个数为1。初始的那个花瓣就落到了地上
现在,小qn想知道,经过k次生长之后,树上和地上的总花瓣个数是多少?
推论:斐波那契数列前n项和为f[n+2]-1,之后用矩阵快速幂即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int mod=998244353;
ll k;
class Matrix{
public:
ll Mat[2][2];
Matrix(){
memset(Mat,0,sizeof(Mat));
}
Matrix operator *(Matrix a)
{
Matrix res;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
for(int k=0;k<2;k++)
{
res.Mat[i][j]=(res.Mat[i][j]+Mat[i][k]*a.Mat[k][j]%mod)%mod;
}
}
}
return res;
}
};
Matrix qmi(ll x,Matrix base)
{
Matrix ans;
ans.Mat[0][0]=1;
ans.Mat[1][1]=1;
while(x)
{
if(x&1) ans=ans*base;
x>>=1;
base=base*base;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>k;
if(k==0)
{
cout<<1<<endl;
return 0;
}
Matrix base;
base.Mat[0][0]=1;
base.Mat[0][1]=1;
base.Mat[1][0]=1;
Matrix h;
h.Mat[0][0]=1;
h.Mat[0][1]=1;
h=h*(qmi(k-1,base));
ll sum=h.Mat[0][0];
Matrix g;
g.Mat[0][0]=1;
g.Mat[0][1]=1;
g=g*(qmi(k,base));
sum=(sum+g.Mat[0][0]-1)%mod;
cout<<sum<<endl;
}