"Topic link": Click here~~
Time limit:10000msSingle Point time limit:1000msMemory Limit:256MB
Describe
Dominoes, an ancient toy. Today we are going to look at the problem of Domino coverage:
We have a 2xN strip board and then use the 1x2 dominoes to cover the entire board. How many different coverage methods are there for this chessboard?
For example, for a board with a length of 1 to 3, we have the following types of coverage:
Hint: Domino Overlay
Tip: How to quickly calculate results
Input
Line 1th: an integer n. Represents the board length. 1≤n≤100,000,000
Output
Line 1th: An integer representing the number of coverage scenarios MOD 19999997
-
-
Sample input
-
-
62247088
-
-
Sample output
-
-
17748018
fast power of "thought" Matrix
We consider how to place the new Domino (blue) in the case where a partial domino (gray) has been placed:
The right side of the situation is impossible, otherwise there will always be more than one lattice no way to place dominoes. Or the gray portion of the lattice is an odd number, it can not be placed through a 1x2 dominoes.
so by looking at the above, we can find:
at the end of any placement scenario, the first two scenarios must be met. The gray part corresponds to the placement scheme of the length N-1 and N-2. Thus, we can get a recursive formula:
F[n] = f[n-1] + f[n-2];
does this formula look familiar? That's right, that's our Fepolaci series.
f[0]=1,f[1]=1,f[2]=2,...
When n is very small, we can calculate it directly by the recursive formula. When n is very large, as long as our computer is good enough, we can still calculate it directly from the recursive formula.
But we learn the algorithm, always such a direct enumeration is not very low, so we have to use a good algorithm to speed up (loaded x).
In fact, for this linear recursion, we can use matrix multiplication to find the nth term. For the Fibonacci sequence of the subject, we want to find a 2x2 matrix M that makes (a, b) x M = (b, a+b), where (A, b) and (b, a+b) are all 1x2 matrices.
Obviously, just take m = [0, 1; 1, 1] on it:
further get:
so the next question is, can you quickly calculate the m^n? Let's start by analyzing the power operation. Since the multiplication is to satisfy the binding law, we have:
you may wish to k[1]. K[J] A better division?
where (k[1],k[2]...k[j]) 2 means that n is represented as a number for each digit after the binary number. The above formula satisfies such a property:
combining the two we can get an algorithm:
1. First calculate all {a^1, a^2, a^4 ... a^ (2^j)}, because the sequence satisfies the recursive formula, the time complexity is O (logn)
2. The exponent n binary, and then use the formula to multiply the corresponding a^j to calculate the a^n, the time complexity is still O (logn)
The total time complexity is O (logn)
this algorithm, because it can find a power in a short time, we call the "fast power" algorithm.
Code:
#include <bits/stdc++.h>using namespace std; #define LL Long Longconst ll mod=19999997; ll N;int i,j;struct matrlc{ ll mapp[2][2];} ans,base; MATRLC unit= {1,0,0,1}; MATRLC mult (MATRLC A,MATRLC b) { MATRLC C; for (int i=0, i<2; i++) for (int j=0; j<2; j + +) { c.mapp[i][j]=0; for (int k=0; k<2; k++) c.mapp[i][j]+= (a.mapp[i][k]*b.mapp[k][j])%mod; C.mapp[i][j]%=mod; } return c;} ll Pow (ll N) { base.mapp[0][0] =base.mapp[0][1]=base.mapp[1][0]=1; base.mapp[1][1]=0; Ans.mapp[0][0] = ans.mapp[1][1] = 1;//ans initialized to the unit matrix ans.mapp[0][1] = ans.mapp[1][0] = 0; while (n) { if (n&1) Ans=mult (ans,base); Base=mult (base,base); n>>=1; } return ans.mapp[0][1]%mod;} int main () { scanf ("%lld", &n); printf ("%lld\n", pow (n+1)%mod); return 0;}
Hihocoder #1143: Domino Overlay problem • One