【NOIP提高组】天使的分裂

本文介绍了一种使用矩阵乘法快速幂解决特定数列求和问题的方法。通过构造五元数组来实现状态转移,最终高效地计算出目标值。

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

Description

这里写图片描述

Data Constraint

这里写图片描述

Solution

看到数据范围显然就是矩阵乘法快速幂了,那么问题的关键就在于推出转移矩阵。设Gi表示Fi,利用Fi1Fi2组合成Fi,容易推出Fi=Fi1+Fi2+fi1+fi2。刚开始设出了一个四元数组[f0,f1,G0,G1],但是推不出来,发现老是缺了一点什么,之前处理电脑问题浪费了不少时间,因为当时时间已经剩下不多,所以有点急躁,不断地把所有元素都列出来,最后发现自己too young了,G不能单独推导出来,一定要连带上F,于是就有了最终成型的五元数组[Fi1,Fi,fi1,fi,Gi]>[Fi,Fi+1,fi,fi+1,Gi+1],快速幂解决。

Code

const mo=998244353;
var
    z:array[0..100,1..5,1..5] of int64;
    c:array[0..100] of int64;
    a,t:array[1..5] of int64;
    sum,i,j,k:longint;
    ans,n:int64;
begin
    sum:=1;
    z[1,1,1]:=0;z[1,1,2]:=1;z[1,1,3]:=0;z[1,1,4]:=0;z[1,1,5]:=1;
    z[1,2,1]:=1;z[1,2,2]:=1;z[1,2,3]:=0;z[1,2,4]:=0;z[1,2,5]:=1;
    z[1,3,1]:=0;z[1,3,2]:=1;z[1,3,3]:=0;z[1,3,4]:=1;z[1,3,5]:=1;
    z[1,4,1]:=0;z[1,4,2]:=1;z[1,4,3]:=1;z[1,4,4]:=1;z[1,4,5]:=1;
    z[1,5,1]:=0;z[1,5,2]:=0;z[1,5,3]:=0;z[1,5,4]:=0;z[1,5,5]:=1;
    readln(n);
    if n=0 then
    begin
        writeln(1);
        exit;
    end;
    if n=1 then
    begin
        writeln(3);
        exit;
    end;
    dec(n);
    a[1]:=1;a[2]:=2;a[3]:=1;a[4]:=1;a[5]:=3;c[1]:=1;
    while c[sum]*2<=n do
    begin
        inc(sum);
        c[sum]:=c[sum-1]*2;
        for i:=1 to 5 do
            for j:=1 to 5 do
                for k:=1 to 5 do z[sum,i,j]:=(z[sum,i,j]+(z[sum-1,i,k]*z[sum-1,k,j])mod mo)mod mo;
    end;
    while n>0 do
    begin
        while c[sum]>n do dec(sum);
        n:=n-c[sum];
        fillchar(t,sizeof(t),0);
        for j:=1 to 5 do
            for k:=1 to 5 do t[j]:=(t[j]+(a[k]*z[sum,k,j])mod mo)mod mo;
        a:=t;
    end;
    writeln(a[5]);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值