Luo Gu P.1939 Matrix Acceleration Template

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

 

Matrix fast exponentiation

Fibonacci sequence

 

First look at the fast exponentiation method of the matrix of the Fibonacci sequence:

 There is a matrix of 1*2 |f[n-2],f[n-1]|, to multiply it by a 2*2 matrix, so that the resulting matrix is ​​|f[n-1],f[ n]|, ie |f[n-1],f[n-2]+f[n-1]|

Then the matrix is

0  1

1  1

First row and first column: f[n-2]*0+f[n-1]*1=f[n-1]

The first row and the second column: f[n-2]*1+f[n-1]*1=f[n]

 

Similarly, for this question:


 There is a matrix of 1*3 |f[n-3],f[n-2],f[n-1]|, to multiply it by a 3*3 matrix, so that the resulting matrix is ​​|f[ n-2],f[n-1],f[n]|, ie |f[n-2],f[n-1],f[n-3]+f[n-1]|

 

 

 

Then this matrix is

0  0  1

1  0  0

0  1  1

 

code

 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\n",(ANS.m[1][1]+ANS.m[2][1]+ANS.m[3][1])%RQY);
47     }
48 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324475010&siteId=291194637