C-Gauss Fibonacci
Time limit:1000 msMemory limit:32768kb64bit Io format:% I64d & % i64u
Submit statusappoint description:
System crawler)
Description
Without expecting, angel replied quickly. she says: "I 'v heard that you' r a very clever boy. so if you wanna me be your GF, you shoshould solve the problem called GF ~. "
How good an opportunity that gardon can not give up! The "problem gf" told by Angel is actually "Gauss Fibonacci ".
As we know, Gauss is the famous mathematician who worked out the sum from 1 to 100 very quickly, and Fibonacci is the crazy man who has Ted some numbers.
Arithmetic progression:
G (I) = K * I + B;
We assume K and B are both non-nagetive integers.
Fibonacci numbers:
F (0) = 0
F (1) = 1
F (n) = f (n-1) + f (n-2) (N> = 2)
The Gauss maid is described as follows:
Given K, B, n, calculate the sum of every F (G (I) for 0 <= I <n
The answer may be very large, so you shoshould divide this answer by M and just output the remainder instead.
Input
The input contains serveral lines. For each line there are four non-nagetive integers: K, B, n, m
Each of them will not exceed 1,000,000,000.
Output
For each line input, out of the value described above.
Sample Input
2 1 4 1002 0 4 100
Sample output
2112
It is also a classic question about the rapid power matrix solution for binary classification. It is mainly about whether the matrix can be constructed or not. Then you can solve the question. If not, you will not have any ideas for this question.
Paste the Code:
/* Constructor matrix: | 1 1 | F (2) F (1) | A = | 1 0 | = | F (1) f (0) | 1 1 | ^ B | f (B + 1) F (B) | a ^ B = | 1 0 | = | F (B) f (b-1) | F (B) = matrix [0] [1] = matrix [1] [0]; first entry: A ^ B public ratio: A ^ K is: n can further simplify the problem because the addition of the matrix also conforms to the allocation law. We propose a ^ B to form such a formula: A ^ B * (I + A ^ K + (a ^ K) ^ 2 + .... + (a ^ K) ^ (N-1) both a ^ B and a ^ K can be calculated using the method we mentioned earlier, how to solve the remaining part of accumulation? Set a ^ K = B to G (n) = I +... + B ^ (N-1), I = n/2 If n is an even number, g (n) = g (I) + g (I) * B ^ I = g (I) * (I + B ^ (I); If n is an odd number, g (n) = I + g (I) * B + g (I )*( B ^ (I + 1) = g (N-1) + B ^ N; (the previous equation may be faster, but more concise) let's set this matrix to B Io I, where o is the zero matrix, and I is the Multiplication Side of the unit matrix to get B ^ 2 I + Bo I multiplication, B ^ 3 I + B + B ^ 2O I is obtained by multiplying the four sides, and B ^ 4 I + B + B ^ 2 + B ^ 3O I has been converted to the power of the matrix, continue to use our binary or binary method to directly obtain the power */# include <stdio. h> # include <string. h ># include <iostream >#include <string> using namespace STD; int K, B, n, m; struct matrix {int date [2] [2]; matrix sete () {for (INT I = 0; I <2; I ++) {for (Int J = 0; j <2; j ++) {date [I] [J] = (I = = J) ;}} matrix add (matrix m) {matrix ans; memset (ans. date, 0, sizeof (ans. date); For (INT I = 0; I <2; I ++) {for (Int J = 0; j <2; j ++) {ans. date [I] [J] = (date [I] [J] + M. date [I] [J]) % m ;}return ans;} matrix MUL (matrix m) {matrix E; For (INT I = 0; I <2; I ++) {for (Int J = 0; j <2; j ++) {e. date [I] [J] = 0; For (int K = 0; k <2; k ++) {e. date [I] [J] + = (long INT) date [I] [k] * m. date [k] [J] % m;} e. date [I] [J] % = m ;}} Return e ;}} A; matrix quick_pow (matrix m, int N) {matrix ans; ans. sete (); While (n) {If (N & 1) {ans = ans. mul (m);} M = m. mul (m); N >>= 1;} return ans;} matrix binary_search (matrix m, int N) {If (n = 1) {return m ;} if (N & 1) {return binary_search (m, n-1 ). add (quick_pow (m, n);} else {matrix E; E. sete (); Return binary_search (m, n> 1 ). mul (quick_pow (m, n> 1 ). add (E) ;}} int main () {. date [0] [0] = 1;. date [0] [1] = 1;. date [1] [0] = 1;. date [1] [1] = 0; while (scanf ("% d", & K, & B, & N, & M )! = EOF) {matrix E; E. sete (); matrix ans = quick_pow (A, B ). mul (E. add (binary_search (quick_pow (A, K), n-1); printf ("% d \ n", ans. date [0] [1] % m);} // system ("pause"); Return 0 ;}