洛谷 P2044 [NOI2012]随机数生成器

题意简述

读入X[0], m, a, c, n和g
$ X[n+1]=(a*X[n]+c)mod m $
求X数列的第n项对g取余的值。

题解思路

矩阵加速
设$$ F=egin{bmatrix} a&01&1end{bmatrix}, G=egin{bmatrix} X[0]cend{bmatrix}$$
则$$ egin{bmatrix} X[n]cend{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
", x0); return 0; }
	b = Mul(c, _pow(a, n));
	printf("%lld
", (b.a[1][1] + mod) % mod % g);
}
原文地址:https://www.cnblogs.com/xuyixuan/p/9806714.html