Description
Input
一个整数n
Output
一行,一个整数,表示第0天到第n天的评估函数的值的和。
Sample Input
Input 1
5
Input 2
666666
Input 3
2147483648
Sample Output
Output 1
76
Output 2
324016098
Output 3
932937567
Data Constraint
分析
题目中的数非常特殊,是斐波拉契数列的数。
那么,这些数满足相邻两个相加可以得到一个新的数。
利用这个性质,我们可以推出递推式:
Fi=Fi−1+Fi−2+fi
这是一个
O(n)
的
可以通过矩阵乘法快速幂优化到
logn
code(c++)
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#define _ %998244353
using namespace std;
struct note
{
long long w[5];
};
long long jz[5][5]={
{0,1,0,0,0},
{1,1,1,1,0},
{0,0,0,1,0},
{0,0,1,1,0},
{1,1,1,1,1}
};
note ans;
long long s[5][5],t[5][5],n;
note times(note a)
{
note c;
memset(c.w,0,sizeof(c.w));
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
c.w[i]=(c.w[i]+a.w[j]*s[i][j]_)_;
return c;
}
int main()
{
scanf("%lld",&n);
memset(ans.w,0,sizeof(ans.w));
memcpy(s,jz,sizeof(s));
ans.w[0]=1;
ans.w[1]=2;
ans.w[2]=1;
ans.w[3]=1;
ans.w[4]=3;
if(n==0)
{
printf("1\n");
return 0;
}
n--;
while(n)
{
if(n%2)ans=times(ans);
n/=2;
memset(t,0,sizeof(t));
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
for(int k=0;k<5;k++)
t[i][j]=(t[i][j]+s[i][k]*s[k][j]_)_;
memcpy(s,t,sizeof(s));
}
printf("%lld\n",ans.w[4]);
}