zoukankan      html  css  js  c++  java
  • 「题解」洛谷 P2044 [NOI2012]随机数生成器

    题目

    P2044 [NOI2012]随机数生成器

    简化题意

    (large x_{i + 1} = (ax_i + c) mod m) 的第 (n) 项。

    (large 1 leq n leq 10 ^ {18})

    思路

    矩阵乘法。

    递推用的矩阵也很好求。

    (large left[egin{array}{ccc}x_i & cend{array} ight] imes left[egin{array}{ccc}a & 1 \ 1 & 1end{array} ight] = left[egin{array}{ccc}x_{i + 1} & cend{array} ight])

    小心模数很大,乘起来会爆long long所以要用龟速乘。

    Code

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    
    typedef long long ll;
    ll m, a, c, x0, n, g;
    
    ll qmul(ll x, ll y) {
        ll ans = 0;
        while (y) {
            if (y & 1) ans = ans + x, ans %= m;
            x = (x + x) % m;
            y >>= 1;
        }
        return ans % m;
    }
    
    struct Matrix {
        ll jz[4][4];
        Matrix() { memset(jz, 0, sizeof jz); }
        void one() {
            for (int i = 1; i <= 4; ++i) jz[i][i] = 1;
        }
        friend Matrix operator * (Matrix a, Matrix b) {
            Matrix c;
            for (int k = 1; k <= 2; ++k) {
                for (int i = 1; i <= 2; ++i) {
                    for (int j = 1; j <= 2; ++j) {
                        c.jz[i][j] = (c.jz[i][j] + qmul(a.jz[i][k], b.jz[k][j])) % m;
                    }
                }
            }
            return c;
        }
    };
    
    Matrix qpow(Matrix a, ll b) {
        Matrix ans, base = a;
        ans.one();
        while (b) {
            if (b & 1) ans = ans * base;
            base = base * base;
            b >>= 1;
        }
        return ans;
    }
    
    int main() {
        scanf("%lld %lld %lld %lld %lld %lld", &m ,&a, &c, &x0, &n, &g);
        Matrix b, nor;
        b.jz[1][1] = a % m, b.jz[1][2] = 0, b.jz[2][1] = 1, b.jz[2][2] = 1;
        nor.jz[1][1] = x0 % m, nor.jz[1][2] = c % m;
        b = qpow(b, n);
        Matrix ans;
        for (int k = 1; k <= 2; ++k) {
            for (int i = 1; i <= 1; ++i) {
                for (int j = 1; j <= 2; ++j) {
                    ans.jz[i][j] = (ans.jz[i][j] + qmul(nor.jz[i][k], b.jz[k][j])) % m;
                }
            }
        }
        std::cout << ans.jz[1][1] % g<< '
    ';
        return 0;
    }
    
  • 相关阅读:
    Spring+Mybatis+Maven+MySql搭建实例
    Spring+Mybatis+SpringMVC+Maven+MySql搭建实例
    SQL GROUP BY 语句
    SQL SUM() 函数
    SQL MIN() 函数
    SQL MAX() 函数
    SQL LAST() 函数
    SQL FIRST() 函数
    SQL COUNT() 函数
    SQL AVG() 函数
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13604804.html
Copyright © 2011-2022 走看看