洛谷 P2044 [NOI2012]隨機數生成器
阿新 • • 發佈:2018-11-11
題意
讀入X[0], m, a, c, n和g
$ X[n+1]=(a*X[n]+c)\mod m $
求X數列的第n項對g取餘的值。
題解
矩陣加速
設\[ F=\begin{bmatrix} a&0\\1&1\end{bmatrix}, G=\begin{bmatrix} X[0]\\c\end{bmatrix}\]
則\[ \begin{bmatrix} X[n]\\c\end{bmatrix} = G * F ^ n (n > 0)\]
乘法用快速乘
程式碼
#include <cstdio> typedef long long ll; int T, N, g; ll n, m, aa, cc, x0, mod; struct Matrix { ll a[4][4]; Matrix& operator =(const Matrix& x) { for (register int i = 1; i <= N; ++i) for (register int j = 1; j <= N; ++j) a[i][j] = x.a[i][j]; return *this; } }; Matrix a, b, c; ll _mul(ll x, ll y, ll s = 0) { for (; y; y >>= 1, x = (x + x) % mod) if (y & 1) s = (s + x) % mod; return s; } Matrix Mul(const Matrix& x, const Matrix& y) { Matrix s; for (register int i = 1; i <= N; ++i) for (register int j = 1; j <= N; ++j) s.a[i][j] = 0; for (register int i = 1; i <= N; ++i) for (register int j = 1; j <= N; ++j) for (register int k = 1; k <= N; ++k) s.a[i][j] = (s.a[i][j] + _mul(x.a[i][k], y.a[k][j])) % mod; return s; } Matrix _pow(Matrix x, ll y) { Matrix s; for (register int i = 1; i <= N; ++i) for (register int j = 1; j <= N; ++j) s.a[i][j] = (i == j); for (; y; y >>= 1, x = Mul(x, x)) if (y & 1) s = Mul(s, x); return s; } int main() { N = 2; scanf("%lld%lld%lld%lld%lld%d", &m, &aa, &cc, &x0, &n, &g); mod = m; c.a[1][1] = x0; c.a[1][2] = cc; a.a[1][1] = aa; a.a[2][1] = a.a[2][2] = 1; if (n <= 0) {printf("%lld\n", x0); return 0; } b = Mul(c, _pow(a, n)); printf("%lld\n", (b.a[1][1] + mod) % mod % g); }