AcWing 1304. 佳佳的斐波那契

AcWing 1304. 佳佳的斐波那契

一、题目描述

佳佳对数学,尤其对数列十分感兴趣。

在研究完 Fibonacci 数列后,她创造出许多稀奇古怪的数列。

例如用 S(n) 表示 Fibonaccin 项和 mod m 的值,即 S(n)=(F1+F2++Fn) mod m,其中 F1=F2=1,Fi=Fi1+Fi2

可这对佳佳来说还是小菜一碟。

终于,她找到了一个自己解决不了的问题。

T(n)=(F1+2F2+3F3++nFn) mod m 表示 Fibonacci 数列前 n 项变形后的和 mod m 的值。

现在佳佳告诉你了一个 nm,请求出 T(n) 的值。

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

输出格式
共一行,输出 T(n) 的值。

数据范围
1n,m2311

输入样例
5 5

输出样例
1

样例解释
T(5)=(1+2×1+3×2+4×3+5×5) mod 5=1

二、推导过程

Sn=F1+F2++Fn=i=1nFiTn=F1+2F2+...+nFn=i=1niFi

我们需要利用Tn构造新的数列,从而消去变量i,最后再反解出Tn

nSnTn=(n1)F1+(n2)F2+...+Fn1

Cn=nSnTn

Cn=(n1)F1+(n2)F2+...+Fn1 

Cn+1=nF1+(n1)F2+...+Fn 

② 式 - ① 式

Cn+1Cn=F1+F2+F3+...+Fn=Sn

于是我们只需维护如下矩阵即可

(fn+1fnsncn)

有如下等式:

(fn+1fnsncn)×(1110100000110001)=(fn+2fn+1sn+1cn+1)

然后直接使用矩阵快速幂便可以求解

初始矩阵

(f2f1s1c1)=(1110)

递推式

(fn+1fnsncn)=(f2f1s1c1)×(1110100000110001)n1

答案
Tn=nSnCn=n×b[0][2]b[0][3]

Code

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"

const int N = 4;
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);
}
int main() {
    int b[N][N] = {1, 1, 1, 0};
    int m[N][N] = {
        {1, 1, 1, 0},
        {1, 0, 0, 0},
        {0, 0, 1, 1},
        {0, 0, 0, 1}};

    cin >> n >> mod;
    for (int i = n - 1; i; i >>= 1) {
        if (i & 1) mul(b, m, b);
        mul(m, m, m);
    }

    int t = (n * b[0][2]) - b[0][3];
    t = (t % mod + mod) % mod;
    printf("%lld\n", t);
    return 0;
}

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