题目
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
数据范围
70%:n<=106
100%:n<=1018
比赛时の想法
70%的递推还是很好想的吧,然而早就忘了矩阵乘法了233~
正解
首先递推式:F[i]:=F[i-1]+F[i-2]+f[i](可以自行分析一下连线的规律~)
那么我们设置一个5*5的矩阵的说我们可以设置一个5 *5的矩阵,然后快速幂一下就可以了
关于矩阵乘法
由于我忘记如何van矩阵乘法了,就在这里打一下方便以后看QAQ
首先初始状态是a,然后我们构建一个矩阵,使得a*b就等于a中的变量i+1后各个量的值。那么最终我们的答案就是a∗bn,我们知道,矩阵乘法是有结合律的,所以我们可以用快速幂求出bn,然后再乘一个a就可以了。构建矩阵的话就找一下几个量之间的关系就好咯QAQ
感觉自己这方面有点辣鸡啊~
快速幂的时候有c[i,j]=a[i,k]*b[k,j] 如果a是一维的那么i就恒为1
贴代码
const
md=998244353;
var
a:array[1..5]of int64=(1,0,1,0,1);
cc:array[1..5]of int64;
e,q:array[1..5,1..5]of int64;
b:array[1..5,1..5]of int64=((1,1,0,0,1),
(1,0,0,0,1),
(1,0,1,1,1),
(1,0,1,0,1),
(0,0,0,0,1));
l,x,n:int64;
i,j,k:longint;
procedure quick;
var
i,j,k:longint;
begin
fillchar(e,sizeof(e),0);
for i:=1 to 5 do
for j:=1 to 5 do
for k:=1 to 5 do
e[i,j]:=(e[i,j]+b[i,k]*q[k,j]) mod md;
b:=e;
end;
procedure quick1;
var
i,j,k:longint;
begin
fillchar(e,sizeof(e),0);
for i:=1 to 5 do
for j:=1 to 5 do
for k:=1 to 5 do
e[i,j]:=(e[i,j]+q[i,k]*q[k,j]) mod md;
q:=e;
end;
begin
readln(n);
x:=n;
q:=b;
dec(n);
while n>0 do
begin
if n mod 2=1 then quick;
quick1;
n:=n div 2;
end;
for j:=1 to 5 do
for k:=1 to 5 do
cc[j]:=(cc[j]+a[k]*b[k,j]) mod md;
if x=0 then cc[5]:=1;
writeln(cc[5]);
end.