zoukankan      html  css  js  c++  java
  • 【洛谷P1939】 矩阵加速模板

    https://www.luogu.org/problemnew/show/P1939

    矩阵快速幂

    斐波那契数列

    首先看一下斐波那契数列的矩阵快速幂求法:

     有一个矩阵1*2的矩阵|f[n-2],f[n-1]|,要使它乘一个2*2的矩阵,使得到的矩阵为|f[n-1],f[n]|,即|f[n-1],f[n-2]+f[n-1]|

    则该矩阵为

    0  1

    1  1

    第一行第一列:f[n-2]*0+f[n-1]*1=f[n-1]

    第一行第二列:f[n-2]*1+f[n-1]*1=f[n]

    同理,对于本题:


     有一个矩阵1*3的矩阵|f[n-3],f[n-2],f[n-1]|,要使它乘一个3*3的矩阵,使得到的矩阵为|f[n-2],f[n-1],f[n]|,即|f[n-2],f[n-1],f[n-3]+f[n-1]|

    那么这个矩阵为

    0  0  1

    1  0  0

    0  1  1

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define ll long long
     5 using namespace std;
     6 const ll RQY = 1000000007;
     7 ll t,n;
     8 struct Matrix
     9 {
    10     ll m[4][4];
    11 } A,ANS,One;
    12 Matrix times(Matrix X,Matrix Y)
    13 {
    14     Matrix Ans;
    15     for(int i=1;i<=3;i++)
    16      for(int j=1;j<=3;j++)
    17       Ans.m[i][j]=(X.m[i][1]*Y.m[1][j]%RQY+X.m[i][2]*Y.m[2][j]%RQY+X.m[i][3]*Y.m[3][j]%RQY)%RQY;
    18     return Ans;
    19 }
    20 Matrix qpow(Matrix X,ll k)
    21 {
    22     Matrix S=One;
    23     while(k)
    24     {
    25         if(k&1) S=times(S,X);
    26         k>>=1;
    27         X=times(X,X);
    28     }
    29     return S;
    30 }
    31 int main()
    32 {
    33     scanf("%lld",&t);
    34     One.m[1][1]=1;
    35     One.m[2][2]=1;
    36     One.m[3][3]=1;
    37     A.m[1][3]=1;
    38     A.m[2][1]=1;
    39     A.m[3][2]=1;
    40     A.m[3][3]=1;
    41     while(t--)
    42     {
    43         scanf("%lld",&n);
    44         n-=1;
    45         ANS=qpow(A,n);
    46         printf("%lld
    ",(ANS.m[1][1]+ANS.m[2][1]+ANS.m[3][1])%RQY);
    47     }
    48 }
  • 相关阅读:
    Linux下SSH的Log文件路径
    Linux下压缩与解压命令tar
    Linux命令之at
    Linux下nice/renice命令小结
    Linux命令详解nice
    LVM---动态调整磁盘容量
    VT100字体
    Linux命令之WC
    for name in loop Shell
    Bind9用view配主从
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/8858394.html
Copyright © 2011-2022 走看看