19年牛客暑期多校训练营第五场 B-generator 1 (十进制矩阵快速幂)

链接: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 ;
}

 

你可能感兴趣的:(快速幂)