【NOIP2016提高A组模拟9.24】天使的分裂

本文介绍了一种使用矩阵快速幂解决特定递推问题的方法,并给出了详细的实现步骤与代码示例。针对递推式 F[i] = F[i-1] + F[i-2] + f[i],文章构建了一个5x5的矩阵并利用快速幂技巧高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

这里写图片描述

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后各个量的值。那么最终我们的答案就是abn,我们知道,矩阵乘法是有结合律的,所以我们可以用快速幂求出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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值