【luogu P1939 【模板】矩阵加速(数列)】 题解

题目链接:https://www.luogu.org/problemnew/show/P1939

对于矩阵推序列的式子:

由题意知:

f[x+1] =1f[x] + 0f[x-1] + 1f[x-2]
f[x] = 1
f[x] + 0f[x-1] + 0f[x-2]
f[x-1] = 0f[x] + 1f[x-1] + 0*f[x-2]

所以矩阵初项的系数:
1 1 0
0 0 1
1 0 0

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn = 110;
const int mod = 1000000007;
struct Matrix{
    ll m[maxn][maxn];
}A, E, Ans;
ll n, q[maxn];
Matrix mul(Matrix A, Matrix B)
{
    Matrix C;
    for(int i = 1; i <= 3; i++)
        for(int j = 1; j <= 3; j++)
        {
            C.m[i][j] = 0;
            for(int k = 1; k <= 3; k++)
                C.m[i][j] = (C.m[i][j] + A.m[i][k] * B.m[k][j] % mod) % mod;
        }
    return C;
}
Matrix qpow(Matrix A, ll k)
{
    Matrix S = E;
    while(k)
    {
        if(k & 1) S = mul(S, A);
        A = mul(A, A);
        k = k >> 1;
    }
    return S;
}
int main()
{
    cin>>n;
    E.m[2][2] = 1;
    E.m[1][1] = 1;
    E.m[3][3] = 1;
    A.m[1][1] = 1;
    A.m[1][2] = 1;
    A.m[2][3] = 1;
    A.m[3][1] = 1;

    for(int i = 1; i <= n; i++)
    {
        ll k;
        cin>>k;
        Ans = qpow(A, k);
        cout<<Ans.m[1][2]<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/MisakaAzusa/p/9648991.html

时间: 2024-10-10 12:29:35

【luogu P1939 【模板】矩阵加速(数列)】 题解的相关文章

P1939 【模板】矩阵加速(数列)

链接:P1939 [模板]矩阵加速(数列) 题目描述 a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 求a数列的第n项对1000000007(10^9+7)取余的值. 输入输出格式 输入格式: 第一行一个整数T,表示询问个数. 以下T行,每行一个正整数n. 输出格式: 每行输出一个非负整数表示答案. 输入输出样例 输入样例#1: 3 6 8 10 输出样例#1: 4 9 19 说明 对于30%的数据 n<=100: 对于60%的数据 n<=2*10^7

[LGOJ]P1939【模板】矩阵加速(数列)[矩阵加速递推]

题面 矩阵加速递推的原理: 首先你得会矩阵乘法与快速幂. 以斐波拉契数列为例, 要从矩阵A \[ \begin{bmatrix} f[n-1] & f[n]  \end{bmatrix} \] 得到矩阵B \[ \begin{bmatrix} f[n] & f[n+1]  \end{bmatrix} \] 显然可以\[\begin{bmatrix} f[n-1] & f[n] \end{bmatrix}\times \begin{bmatrix}  0 & 1\\ 1 &a

斐波那契数列F(n)【n超大时的(矩阵加速运算) 模板】

hihocoder #1143 : 骨牌覆盖问题·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘.对于这个棋盘,一共有多少种不同的覆盖方法呢? 举个例子,对于长度为1到3的棋盘,我们有下面几种覆盖方式: 提示:骨牌覆盖 提示:如何快速计算结果 输入 第1行:1个整数N.表示棋盘长度.1≤N≤100,000,000 输出 第1行:1个整数,表示

【Luogu】P2886牛继电器(矩阵加速floyd)

题目链接 矩阵加速floyd……牛逼牛逼. 注意离散化,注意更新的时候要用旧的权值矩阵更新. #include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<algorithm> #define maxn 300 #define check(x) if(x==0) x=++size; using namespace std; inline long lo

【矩阵加速】 矩阵 快速幂

矩阵的快速幂是用来高效地计算矩阵的高次方的.将朴素的o(n)的时间复杂度,降到log(n). 这里先对原理(主要运用了矩阵乘法的结合律)做下简单形象的介绍: 一般一个矩阵的n次方,我们会通过连乘n-1次来得到它的n次幂. 但做下简单的改进就能减少连乘的次数,方法如下: 把n个矩阵进行两两分组,比如:A*A*A*A*A*A => (A*A)*(A*A)*(A*A) 这样变的好处是,你只需要计算一次A*A,然后将结果(A*A)连乘自己两次就能得到A^6,即(A*A)^3=A^6.算一下发现这次一共乘

算法学习笔记 递归之 快速幂、斐波那契矩阵加速

递归的定义 原文地址为:http://blog.csdn.net/thisinnocence 递归和迭代是编程中最为常用的基本技巧,而且递归常常比迭代更为简洁和强大.它的定义就是:直接或间接调用自身.经典问题有:幂运算.阶乘.组合数.斐波那契数列.汉诺塔等.其算法思想: 原问题可分解子问题(必要条件): 原与分解后的子问题相似(递归方程): 分解次数有限(子问题有穷): 最终问题可直接解决(递归边界): 对于递归的应用与优化,直接递归时要预估时空复杂度,以免出现用时过长或者栈溢出.优化递归就是以

HDU 5564 Clarke and digits 状压dp+矩阵加速

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5564 题意: 求长度在[L,R]范围,并且能整除7的整数的总数. 题解: 考虑最原始的想法: dp[i][j][k]表示长度为i,并且对7取模得到j的以k结尾的数. 则有状态转移方程dp[i+1][(h*10)+l)%7][k]+=dp[i][h][k'](k+k'!=K). 但是i范围是1~10^9,需要矩阵加速. 这里对dp[i][j][k]的[j][k]两个状态进行压缩,得到转移矩阵mat[

【HDU3802】【降幂大法+矩阵加速+特征方程】Ipad,IPhone

Problem Description In ACM_DIY, there is one master called “Lost”. As we know he is a “-2Dai”, which means he has a lot of money.  Well, Lost use Ipad and IPhone to reward the ones who solve the following problem.  In this problem, we define F( n ) a

[HDU2294] Pendant - 矩阵加速递推

Pendant Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1032    Accepted Submission(s): 535 Problem Description On Saint Valentine's Day, Alex imagined to present a special pendant to his girl f