• 【洛谷P1939】矩阵加速(数列)


    Description

    定义序列a的通项公式为$a_i=left{egin{aligned}1 && i leq 3 \a_{i-1}+a_{i-3} && i geq 4end{aligned} ight.$

    求序列a的第n项对1e9+7取模的值

    Solution

    由于n的值很大,所以普通的递推无法解决,我们考虑使用矩阵乘法

    假设$F(n)=egin{bmatrix}a_n & a_{n-1} & a_{n-2}end{bmatrix}$,我们考虑将$F(n-1)$乘上一个矩阵base之后变成$F(n)$

    也就是说$egin{bmatrix}a_{n-1} & a_{n-2} & a_{n-3}end{bmatrix} imes base = egin{bmatrix}a_n & a_{n-1} & a_{n-2}end{bmatrix}$

    显然,我们可以轻易计算出$base=egin{bmatrix}1 & 1 & 0 \0 & 0 & 1 \ 1 & 0 & 0 end{bmatrix}$

    我们定义初始矩阵$a=egin{bmatrix}1 & 1 & 1 end{bmatrix}$,然后利用矩阵快速幂计算$a imes base^{n-3}$即可

    时间复杂度为$O(3^3log_2n)$

    Code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int mod = 1e9 + 7;
     5 int T, n;
     6 struct Matrix {
     7     ll m[4][4];
     8     Matrix() {memset(m, 0, sizeof(m));}
     9     Matrix operator *(const Matrix &x) const {
    10         Matrix ret;
    11         for (register int i = 1; i <= 3; ++i)
    12             for (register int j = 1; j <= 3; ++j)
    13                 for (register int k = 1; k <= 3; ++k)
    14                     ret.m[i][j] = (ret.m[i][j] + m[i][k] * x.m[k][j] % mod) % mod; 
    15         return ret;
    16     }
    17 } a, base;
    18 inline void init() {
    19     base.m[1][1] = 1; base.m[1][2] = 1; base.m[1][3] = 0;
    20     base.m[2][1] = 0; base.m[2][2] = 0; base.m[2][3] = 1;
    21     base.m[3][1] = 1; base.m[3][2] = 0; base.m[3][3] = 0;
    22     a.m[1][1] = 1; a.m[1][2] = 1; a.m[1][3] = 1;
    23 }
    24 void qpow(int p) {
    25     while (p) {
    26         if (p & 1) a = a * base;
    27         base = base * base;
    28         p >>= 1;
    29     }
    30 }
    31 int main() {
    32     scanf("%d", &T);
    33     while (T--) {
    34         init();
    35         scanf("%d", &n);
    36         if (n <= 3) {
    37             puts("1"); continue ;
    38         }
    39         qpow(n - 3);
    40         printf("%lld
    ", a.m[1][1]);
    41     }
    42     return 0;
    43 }
    AC Code
  • 相关阅读:
    反射、面向对象(基础篇)
    配置文件
    模块补充 、迭代器和 生成器
    模块
    正则表达式
    冒泡排序、递归和简单装饰器
    使用Apache Archiva管理Maven仓库
    AppScan9.0.3.5漏洞扫描记录
    Linux环境下安装Websphere8.5.5
    如何排查网络通讯状况
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11335910.html
Copyright © 2020-2023  润新知