How to obtain the nth item quickly when the nth item of the recursive series is required and N is large?
The matrix power can be used to accelerate computing.
We can use a matrix to represent the recurrence formula of a series.
For example, the Fibonacci series can be expressed as [F (n) f (n-1)] = [F (n-1) f (n-2)] [1]
[1 0]
Set a = [1 1]
[1 0]
[F (n) f (n-1)] = [F (n-2) f (n-3)] * a *
[F (n) f (n-1)] = [F (2) F (1)] * a ^ (n-2)
Matrix satisfies the Union law, so first calculate a ^ (n-2), this can be calculated using the general Fast Binary power.
Bestcoder round # Eight 1002
When N is an odd number, F (n) = 2 * F (n-1) + 1
When N is an even number, F (n) = 2 * F (n-1)
Separate the even number to form a separate series B (2 * n) = 2 * B (2 * N-1) + 1 = 4*(2 * N-2) + 2
That is, B (n) = 4 * B (n-1) + 2
When N is an even number, calculate B (n/2 ).
When N is an odd number, calculate B (n/2) * 2 + 1.
Because N is large, it can be accelerated using the matrix's rapid power.
The recursive matrix is [B (n) 2] = [B (n-1] 2] * [4 0]
[1 1]
1 #include <stdio.h> 2 #include <string.h> 3 typedef long long LL; 4 struct Matrix 5 { 6 LL matrix[2][2]; 7 }; 8 int n,m; 9 Matrix operator *(const Matrix &lhs, const Matrix &rhs)10 {11 Matrix res;12 memset(res.matrix, 0 ,sizeof(res.matrix));13 int i,j,k;14 for(k=0; k<2; ++k)15 for(i=0; i<2; ++i)16 {17 if(lhs.matrix[i][k] == 0) continue;18 for(j=0; j<2; ++j)19 {20 if(rhs.matrix[k][j] == 0) continue;21 res.matrix[i][j] = (res.matrix[i][j] + lhs.matrix[i][k] * rhs.matrix[k][j]) % m;22 }23 }24 return res;25 }26 Matrix operator ^(Matrix a, int k)27 {28 Matrix res;29 int i,j;30 for(i=0; i<2; ++i)31 for(j=0; j<2; ++j)32 res.matrix[i][j] = (i == j);33 while(k)34 {35 if(k & 1)36 res = res * a;37 a = a * a;38 k>>=1;39 }40 return res;41 }42 43 int main()44 {45 while(scanf("%d%d",&n,&m)!=EOF)46 {47 Matrix a;48 a.matrix[0][0] = 4;49 a.matrix[0][1] = 0;50 a.matrix[1][0] = a.matrix[1][1] = 1;51 int k = n / 2;52 a = a ^ k;53 LL ans =(2 * a.matrix[1][0]) % m;54 if(n & 1 == 1)55 ans = (ans * 2 + 1) % m;56 printf("%lld\n",ans);57 58 59 }60 return 0;61 }View code
Rapid matrix power --- bestcoder round #8 1002