链接:https://ac.nowcoder.com/acm/contest/885/B
来源:牛客网
题目描述
You are given four positive integers x0,x1,a,bx_0, x_1, a, bx0,x1,a,b. And you know xi=a⋅xi−1+b⋅xi−2x_i = a \cdot x_{i-1} + b \cdot x_{i-2}xi=a⋅xi−1+b⋅xi−2 for all i≥2i \ge 2i≥2.
Given two positive integers n, and MOD, please calculate xnx_nxn modulo MOD.
Does the problem look simple? Surprise! The value of n may have many many digits!输入描述:
The input contains two lines. The first line contains four integers x0,x1,a,bx_0, x_1, a, bx0,x1,a,b (1≤x0,x1,a,b≤1091 \le x_0, x_1, a, b \le 10^91≤x0,x1,a,b≤109). The second line contains two integers n, MOD (1≤n<10(106),109
输出描述:
Print one integer representing the answer.
示例1
输入
复制
1 1 1 1 10 1000000001
输出
复制
89
说明
The resulting sequence x is Fibonacci sequence. The 11-th item is 89.
示例2
输入
复制
1315 521 20185 5452831 9999999999999999999999999999999999999 1000000007
输出
复制
914730061
解题思路:十进制矩阵快速幂。答案为矩阵{{a,b}{1,0}}的n-1次方。
十进制快速幂可参考:Here
/* @Author: Top_Spirit @Language: C++ */ #include
using namespace std ; typedef unsigned long long ull ; typedef long long ll ; const int Maxn = 1e3 + 10 ; const int INF = 0x3f3f3f3f ; const double PI = acos(-1.0) ; const ull seed = 133 ; const int MOD = 51123987 ; struct Node { ll mat[2][2] ; }ans, tmp, O, z ; ll x0, x1, a, b ; ll mod, len ; string n ; void init(){ ans.mat[0][0] = ans.mat[1][1] = 1 ; ans.mat[0][1] = ans.mat[1][0] = 0 ; tmp.mat[0][0] = a ; tmp.mat[0][1] = b ; tmp.mat[1][0] = 1 ; tmp.mat[1][1] = 0 ; } Node getPow(Node a, Node b){ for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++){ z.mat[i][j] = 0 ; for (int k = 0; k < 2; k++){ z.mat[i][j] = (z.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % mod ; } } } return z ; } int main (){ ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ; cin >> x0 >> x1 >> a >> b ; cin >> n >> mod ; len = n.size() ; len-- ; init() ; for (int i = len; i >= 0; i--) { ll cnt = n[i] - '0' ; for (int i = 1; i <= cnt; i++) ans = getPow(ans, tmp) ; O.mat[0][0] = O.mat[1][1] = 1 ; O.mat[0][1] = O.mat[1][0] = 0 ; for (int j = 0; j < 10; j++) O = getPow(O, tmp) ; tmp = O ; } cout << (x1 * ans.mat[1][0] + x0 * ans.mat[1][1]) % mod << endl ; return 0 ; }