AcWing 1303. 斐波那契前 n 项和

AcWing 1303. 斐波那契前 n 项和

一、题目描述

大家都知道 Fibonacci 数列吧,f1=1,f2=1,f3=2,f4=3,,fn=fn1+fn2

现在问题很简单,输入 nm,求 fn 的前 n 项和 Sn mod m

输入格式
共一行,包含两个整数 nm

输出格式
输出前 n 项和 Sn mod m 的值。

数据范围
1n2000000000,1m1000000010

输入样例
5 1000

输出样例
12

二、解题思路

普通的迭代法,是线性的,n的上限是2e9,循环的话会超时,需要想其它办法。

矩阵快速幂

[snfn+1fn]×[abcdefhij]=[sn+1fn+2fn+1]

sn+1=sn×a+fn+1×d+fn×hfn+2=sn×b+fn+1×e+fn×ifn+1=sn×c+fn+1×f+fn×j

根据题目的现实含义:
sn+1=sn+fn+1
fn+2=fn+fn+1

推导出:
a=1,d=1,h=0
b=0,e=1,i=1
c=0,f=1,j=0

整理出矩阵就是:
m=[100111010]

已知 s1=1f2=1f1=1,使用矩阵快速幂可以求解 sn
b=[111]

[s1f2f1]×[100111010]=[s2f3f2]

[s2f3f2]×[100111010]=[s3f4f3]

将 ① 代入 ② 得到:

[s1f2f1]×[100111010]2=[s3f4f3]

通过数学归纳法,得:

[s1f2f1]×[100111010]n1=[snfn+1fn]

三、实现代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
const int N = 3;
int n, mod;

// 矩阵乘法
void mul(int a[][N], int b[][N], int c[][N]) {
    int t[N][N] = {0};
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++)
            for (int k = 0; k < N; k++)
                t[i][j] = (t[i][j] + (a[i][k] * b[k][j]) % mod) % mod;
    }
    memcpy(c, t, sizeof t);
}

signed main() {
    int b[N][N] = {1, 1, 1};
    int m[N][N] = {
        {1, 0, 0},
        {1, 1, 1},
        {0, 1, 0}};

    cin >> n >> mod;

    for (int i = n - 1; i; i >>= 1) {
        if (i & 1) mul(b, m, b);
        mul(m, m, m);
    }
    printf("%d\n", b[0][0]);
}
posted @   糖豆爸爸  阅读(154)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2013-06-04 省内转学出错的解决办法
Live2D
点击右上角即可分享
微信分享提示