P1939 matrix accelerate

       If this problem look at the subject and scope, I first thought of using recursion, but n≤2 × 10 ^ 9, when a recursive, will time out.

Use the matrix to accelerate, then we must first find a matrix (not unique), is multiplied;

[A1, a2, a3] is a 1 × 3 matrix, and I want it is converted to [a2, a3, a4] is a 1 × 3 matrix, it must be looking for a matrix of 3 × 3;

This can be assumed that a 3 × 3 matrix is        thus a2 = a1 × a + a2 × b + a3 × c So a = 0; b = 1; c = 0; Similarly available d = 0; e = 0; f = 1;

 

a4 = a3 + a1 so g = 1; h = 0; i = 1; 3 × 3 matrix thus should      be seen To draw an, it is necessary that the matrix (n-3) th and then by

[A1, a2, a3] as a1, a2, a3 is 1, it can not take the conclusion that [a n-2, a n-1, an]; with r [4] [4] is stored by after a 3 × 3 matrix,

It is an r [1] [3] + r [2] [3] + r [3] [3]; determined to quickly answer by flash power.

 

In fact, this question apply P 3390 fast power matrix code can, so I will not explain, the issue of how quickly the power of the matrix on a blog have been described.

Directly on the complete code:

 

 1 #include<iostream>
 2 using namespace std;
 3 struct hls{
 4     long long s[4][4];
 5 };
 6 hls t,r;
 7 long long k;
 8 const long long m=1000000007;
 9 hls operator * (const hls &a,const hls &b)
10 {
11     hls w;
12     for(int i=1;i<=3;++i)
13     {
14         for(int j=1;j<=3;++j)
15         {
16             w.s[i][j]=0;
17         }
18     }
19     for(int x=1;x<=3;++x)
20     {
21         for(int y=1;y<=3;++y)
22         {
23             for(int z=1;z<=3;++z)
24             {
25                 w.s[x][y]+=(a.s[x][z]%m)*(b.s[z][y]%m);
26                 w.s[x][y]%=m;
27             }
28         }
29     }
30     return w;
31 }
32 int main()
33 {
34     int q;
35     cin>>q;
36     while(q--)
37     {
38         cin>>k;
39         for(int i=1;i<=3;++i)
40         {
41             for(int j=1;j<=3;++j)
42             {
43                 t.s[i][j]=0;
44                 if(i!=j) r.s[i][j]=0;
45                 else r.s[i][j]=1;
46             }
47         }
48         t.s[1][3]++; 
49         t.s[2][1]++; 
50         t.s[3][2]++; 
51         t.s[3][3]++;
52         k=k-3;
53         while(k>0) 
54         {
55             if(k%2==1) r=r*t;
56             t=t*t;
57             k/=2;
58         }
59         cout<<(r.s[1][3]+r.s[2][3]+r.s[3][3])%m<<endl;
60     }
61     return 0;
62 }

 

Guess you like

Origin www.cnblogs.com/zkw666/p/12457407.html