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
G (I) = K * I + B. Find all F (G (I) in the range of N.
Train of Thought: Reference: 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];
The first item is a ^ B.
Public ratio: A ^ K
Number of items: N
Can further simplify the problem
Since the multiplication of the matrix addition also conforms to the allocation Law, we propose a ^ B to form this formula:
A ^ B * (I + A ^ K + (a ^ K) ^ 2 +... + (a ^ K) ^ (N-1 ))
A ^ B and a ^ K can be calculated using the methods we have mentioned earlier. How can we solve the remaining part of accumulation?
Set a ^ K = B
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 it is more concise later)
Let's set such a matrix.
B I
O I
Where o is the zero matrix and I is the unit matrix
Multiply it to get
B ^ 2 I + B
O I
Get
B ^ 3 I + B + B ^ 2
O I
Get
B ^ 4 I + B + B ^ 2 + B ^ 3
O I
Now that the power of the matrix has been converted, we can continue to use our binary or binary method to directly find the power.
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>typedef long long ll;using namespace std;const int maxn = 2;int m;struct Matrix {ll v[maxn][maxn];Matrix() {}Matrix(int x) {init();for (int i = 0; i < maxn; i++) v[i][i] = x;}void init() {memset(v, 0, sizeof(v));}Matrix operator *(Matrix const &b) const {Matrix c;c.init();for (int i = 0; i < maxn; i++)for (int j = 0; j < maxn; j++)for (int k = 0; k < maxn; k++)c.v[i][j] = (c.v[i][j] + (v[i][k]*b.v[k][j])%m) % m;return c;}Matrix operator ^(int b) {Matrix a = *this, res(1);while (b) {if (b & 1)res = res * a;a = a * a;b >>= 1;}return res;}} u, em;Matrix Add(Matrix a, Matrix b) {for (int i = 0; i < maxn; i++)for (int j = 0; j < maxn; j++)a.v[i][j] = (a.v[i][j]+b.v[i][j]) % m;return a;}Matrix BinarySum(Matrix a, int n) {if (n == 1)return a;if (n & 1)return Add(BinarySum(a, n-1), a^n);else return BinarySum(a, n>>1) * Add(u, a^(n>>1));}int main() {int k, b, n;u.init(), em.init();u.v[0][0] = 1, u.v[0][1] = 0, u.v[1][0] = 0, u.v[1][1] = 1;em.v[0][0] = 1, em.v[0][1] = 1, em.v[1][0] = 1, em.v[1][1] = 0;while (scanf("%d%d%d%d", &k, &b, &n, &m) != EOF) {Matrix t1, t2, ans;t1 = em^b;t2 = em^k;ans = Add(u, BinarySum(t2, n-1)) * t1;cout << ans.v[0][1] << endl;}return 0;}
HDU-1588 Gauss Fibonacci (Matrix High-Speed Power + binary algorithm proportional sequence and)