首页 > 其他分享 >NC18987 粉嘤花之恋

NC18987 粉嘤花之恋

时间:2023-08-27 20:23:22浏览次数:27  
标签:begin end Matrix 之恋 花瓣 pmatrix NC18987 mat

题目链接

题目

题目描述

qn是个特别可爱的小哥哥,qy是个特别好的小姐姐,他们两个是一对好朋友 [ cp (划掉~)
又是一年嘤花烂漫时,小qn于是就邀请了qy去嘤花盛开的地方去玩。当qy和qn来到了田野里时,qy惊奇的发现,嘤花花瓣以肉眼可见的速度从树上长了出来。
仔细看看的话,花瓣实际上是以一定规律长出来的,而且,每次张成新的花瓣的时候,上一次的花瓣就会都落到地上,而且不会消失。
花瓣生长的规律是,当次数大于等于2时,第i次长出来的花瓣个数和上一次张出来的花瓣个数的差是斐波那契数列的第i-1项。初始的时候地上没有花瓣,树上的花瓣个数为1,第一次生长的花瓣个数为1。初始的那个花瓣就落到了地上

现在,小qn想知道,经过k次生长之后,树上和地上的总花瓣个数是多少?

ps:斐波那契数列:

​ f[1]=f[2]=1;f[i]=f[i-1]+f[i-2] (i>=2且i ∈ N+)

输入描述

一行一个数k

输出描述

一行一个数m,表示第k次生长过后,树上和地上的总花瓣数是多少。由于答案会很大,请你将答案mod 998244353后输出

示例1

输入

4

输出

12

说明

第一次:树上1,地上1.第二次树上2,地上1+1,第三次树上3,地上1+1+2,第四次树上5,地上1+1+2+3。总共12个

示例2

输入

5

输出

20

说明

第五次树上8,地上1+1+2+3+5。总共20个

备注

对于0%的数据,有k=样例
对于20%的数据,有k<=1'000
对于60%的数据,有k<=1'000'000
对于80%的数据,有k<=1'000'000'000
对于100%的数据,有k<1'000'000'000'000'000'000

题解

知识点:运算优化,线性代数。

设 \(f(i)\) 表示第 \(i\) 次长出来的花瓣数,\(g(i)\) 表示第 \(i\) 次生长后花瓣总数, \(F(i)\) 表示斐波那契数列第 \(i\) 项。

显然,有如下转移:

\[\begin{aligned} \begin{pmatrix} 1 &1 &0 &0\\ 0 &1 &1 &0\\ 0 &0 &1 &1\\ 0 &0 &1 &0\\ \end{pmatrix} \begin{pmatrix} g(i)\\ f(i+1)\\ F(i+1)\\ F(i)\\ \end{pmatrix} = \begin{pmatrix} g(i+1)\\ f(i+2)\\ F(i+2)\\ F(i+1)\\ \end{pmatrix} \end{aligned} \]

我们使用矩阵快速幂优化,有如下等式:

\[\begin{aligned} \begin{pmatrix} 1 &1 &0 &0\\ 0 &1 &1 &0\\ 0 &0 &1 &1\\ 0 &0 &1 &0\\ \end{pmatrix}^k \begin{pmatrix} g(0)\\ f(1)\\ F(1)\\ F(0)\\ \end{pmatrix} = \begin{pmatrix} g(k)\\ f(k+1)\\ F(k+1)\\ F(k)\\ \end{pmatrix} \end{aligned} \]

时间复杂度 \(O(\log k)\)

空间复杂度 \(O(1)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

struct Matrix {
    const static int P;

    int n, m;
    vector<vector<int>> mat;

    Matrix(int _n = 0) :n(_n), m(_n), mat(_n + 1, vector<int>(_n + 1)) { for (int i = 1;i <= n;i++) mat[i][i] = 1; }
    Matrix(int _n, int _m) :n(_n), m(_m), mat(_n + 1, vector<int>(_m + 1)) {}
    Matrix(const vector<vector<int>> &_mat) :n(_mat.size() - 1), m(_mat[1].size() - 1), mat(_mat) {}

    friend Matrix operator*(const Matrix &A, const Matrix &B) {
        Matrix ans(A.n, B.m);
        if (A.m != B.n) return ans;
        for (int i = 1;i <= A.n;i++)
            for (int k = 1;k <= A.m;k++) //a.m == b.n
                for (int j = 1;j <= B.m;j++)
                    ans.mat[i][j] = (ans.mat[i][j] + 1LL * A.mat[i][k] * B.mat[k][j]) % P;
        return ans;
    }

    friend Matrix operator^(Matrix A, ll k) {
        Matrix ans(A.n);
        while (k) {
            if (k & 1) ans = ans * A;
            k >>= 1;
            A = A * A;
        }
        return ans;
    }

    friend ostream &operator<<(ostream &os, const Matrix &A) {
        for (int i = 1; i <= A.n; i++)
            for (int j = 1; j <= A.m; j++)
                os << A.mat[i][j] << " \n"[i != A.n && j == A.m];
        return os;
    }
};

const int P = 998244353;
const int Matrix::P = ::P;

Matrix A(
    {
        {-1,-1,-1,-1,-1},
        {-1, 1, 1, 0, 0},
        {-1, 0, 1, 1, 0},
        {-1, 0, 0, 1, 1},
        {-1, 0, 0, 1, 0}
    }
);

Matrix B(
    {
        {-1,-1},
        {-1, 1},
        {-1, 1},
        {-1, 1},
        {-1, 0},
    }
);

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    ll n;
    cin >> n;
    cout << ((A ^ n) * B).mat[1][1] << '\n';
    return 0;
}

标签:begin,end,Matrix,之恋,花瓣,pmatrix,NC18987,mat
From: https://www.cnblogs.com/BlankYang/p/17660744.html

相关文章

  • 欢迎来到Pia♥Carrot!!4(快餐店之恋4) 汉化启航
    C3汉化工作已经快结束了,当然发布之前还需要进行严格的测试。下一个坑我打算开这个快餐店之恋4 这个系列我就不多说了,1和2很多人在土星机器上玩过的,PSP上也有对应版本和C系列一样是F&C很有名ADV游戏系列 翻译导入工作已经同时进行。文本大小为5MB,比773.8M和C3 2M大很多关......
  • 苏格拉底之恋爱、婚姻、和幸福观点
    柏拉图:老师,什么是恋爱?苏格拉底:你去麦田捡麦穗,记住只能捡一次,不能回头。不一会,柏拉图就回来了,但是却空着手。老师就问他,为何什么都没捡到呀。柏拉图:我走到田间,看到几个特别大特别灿烂的麦穗,可是我总想着前面可能会有更大更好的,于是就没有捡。但是,当我继续往前走后,看到的麦穗,总觉......
  • 【题解】P3920 [WC2014]紫荆花之恋
    思路点分树+根号重构+*高速平衡树。点分树的两种常见用法无非是直接做和路径有关的暴力还有处理这种有关单点和整树的问题,后者的另一个经典题目是P3241[HNOI2015]开店。回到这个题目,处理路径考虑先上点分治,暂时不考虑强制在线的限制。因为每次加上一个新点,所以可以考......
  • 倾城之恋
    第一炉香故事内容1.葛薇龙来到姑母家请求帮助,父亲一家因为家庭经济原因准备回上海,葛薇龙想继续留在香港读书。2.在姑妈奢华、精致的房屋里,葛薇龙逐渐为姑妈的招待所俘获......