bzoj 2875 [Noi2012]随机数生成器 矩阵乘法

题面

题目传送门

解法

矩阵乘法sb题

注意整数乘法要使用龟速乘,否则会爆long long

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
struct Matrix {
    int a[4][4];
    void Clear() {memset(a, 0, sizeof(a));}
};
int n, m, a, c, x, g;
int mul(int x, int y) {
    int ret = 0;
    while (y) {
        if (y & 1) ret = (ret + x) % m;
        y >>= 1, x = (x + x) % m;
    }
    return ret;
}
Matrix operator * (Matrix x, Matrix y) {
    Matrix ret; ret.Clear();
    for (int k = 1; k <= 2; k++)
        for (int i = 1; i <= 2; i++)
            for (int j = 1; j <= 2; j++)
                ret.a[i][j] = (ret.a[i][j] + mul(x.a[i][k], y.a[k][j])) % m;
    return ret;
}
Matrix operator ^ (Matrix x, int y) {
    Matrix ret = x; y--;
    while (y) {
        if (y & 1) ret = ret * x;
        y >>= 1, x = x * x;
    }
    return ret;
}
main() {
    cin >> m >> a >> c >> x >> n >> g;  
    Matrix tx, ret; tx.Clear();
    tx.a[1][1] = a, tx.a[1][2] = c;
    tx.a[2][1] = 0, tx.a[2][2] = 1;
    ret.a[1][1] = x, ret.a[2][1] = 1;
    tx = tx ^ n; ret = tx * ret;
    cout << ret.a[1][1] % g << "\n";
    return 0;
}

转载于:https://www.cnblogs.com/copperoxide/p/9476730.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值