多校(第五场)T2(十进制求广义斐波那契)好题

You are given four positive integers x0, x1, a, b. And you know xi=a⋅x(i−1)+b⋅x(i−2) for all i≥2.

Given two positive integers n, and MOD, please calculate x_nx
n 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, b(1≤x0 ,x1,a,b≤10^9).
The second line contains two integers n, MOD (1≤n<10(10^6)),10^9 < MO D≤ 2×10^9, n has no leading zero).
输出描述:
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
题意:
给你一个递推式:
f[2] = x0
f[1] = x1
f[n] = a * f[n - 1] + b * f[n - 2] (i >= 2)
给出:x0, x1, a, b, mod
求f[n]

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e6 + 5;
typedef long long ll;
ll mod;
char str[maxn];
const int mlen = 2;
struct Matrix {
    ll a[mlen][mlen];
    Matrix() {
        MatrixInit();
    }
    void MatrixDiag() {
        MatrixInit();
        for (int i = 0; i < mlen; i++) a[i][i] = 1;
    }
    void MatrixInit() {
        for (int i = 0; i < mlen; i++) 
            for (int j = 0; j < mlen; j++) a[i][j] = 0;
    }
    Matrix MatrixMul(Matrix b) {
        Matrix c;
        for (int i = 0; i < mlen; i++) {
            for (int j = 0; j < mlen; j++) {
                for (int k = 0; k < mlen; k++) {
                    c.a[i][j] = (c.a[i][j] + a[i][k] * b.a[k][j]) % mod;
                }
            }
        }
        return c;
    }
    Matrix MatrixPow(ll n) {
        Matrix ans; ans.MatrixDiag();
        Matrix b = *this;
        while (n) {
            if (n & 1) ans = ans.MatrixMul(b);
            b = b.MatrixMul(b);
            n >>= 1;
        }
        return ans;
    }
};
int main() {
    ll x0, x1, a, b;
    scanf("%lld%lld%lld%lld", &x0, &x1, &a, &b);
    scanf("%s%lld", str + 1, &mod);
    Matrix res, ans;
    res.a[0][0] = a; res.a[0][1] = b; res.a[1][0] = 1; res.a[1][1] = 0;
    ans.MatrixDiag();
    int len = strlen(str + 1);
    for (int i = len; i >= 1; i--) { //十进制求法
        int p = str[i] - '0';
        if (p) {
            Matrix tmp = res.MatrixPow(p);
            ans = ans.MatrixMul(tmp);
        }
        res = res.MatrixPow(10);
    }
    printf("%lld\n", (ans.a[1][0] * x1 + ans.a[1][1] * x0) % mod);
    return 0;
}
全部评论

相关推荐

点赞 评论 收藏
分享
迟缓的斜杠青年巴比Q了:简历被投过的公司卖出去了,我前两天遇到过更离谱的,打电话来问我有没有意向报班学Java学习,服了,还拿我学校一个学长在他们那报班学了之后干了华为OD当招牌
点赞 评论 收藏
分享
mama3925:建议专业技能里测试移到最上面,加粗。然后适当加入些自动化测试工具。第二个项目,第三条亮点最后错别字。然后佬如果对自己很自信的话,可以项目放前面,然后项目里可以编造点测试经历,写在写在项目亮点的前两行。最后可加个自我评价,放个博客或者仓库链接
点赞 评论 收藏
分享
强大的马里奥:我初中同学,没上高中,搞直播,现在提奔驰S450了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务