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

题目大意:给你$m,a,c,X_0,n,g$,求$X_{n+1}=(a\cdot X_n+c) \bmod{m}$,最后输出对$g$取模

题解:矩阵快速幂+龟速乘,这里用了$long\;double$强转

卡点:

C++ Code:

#include <cstdio>
#include <cmath>
using namespace std;
long long m, a, c, x0, n, g;
long long mul(long long a, long long b) {
	long long d = (long long) floor(a * (long double) b / m + 0.5);
	long long res = a * b - d * m;
	if (res < 0) res += m;
	return res;
}
//long long mul(long long a, long long b) {
//	long long res = 0;
//	while (b) {
//		if (b & 1) res = (res + a) % m;
//		b >>= 1;
//		a = (a + a) % m;
//	}
//	return res;
//}
struct matrix {
	long long s[4];
	matrix (long long a, long long b, long long c, long long d) {
		s[0] = a; s[1] = b; s[2] = c; s[3] = d;
	}
	matrix operator * (matrix rhs) {
		matrix res(0, 0, 0, 0);
		res.s[0] = (mul(s[0], rhs.s[0]) + mul(s[1], rhs.s[2])) % m;
		res.s[1] = (mul(s[0], rhs.s[1]) + mul(s[1], rhs.s[3])) % m;
		res.s[2] = (mul(s[2], rhs.s[0]) + mul(s[3], rhs.s[2])) % m;
		res.s[3] = (mul(s[2], rhs.s[1]) + mul(s[3], rhs.s[3])) % m;
		return res;
	}
};
int main() {
	scanf("%lld%lld%lld%lld%lld%lld", &m, &a, &c, &x0, &n, &g);
	matrix base(a, 0, 1, 1), ans(x0, c, 0, 0);
	while (n) {
		if (n & 1) ans = ans * base;
		base = base * base;
		n >>= 1;
	}
	printf("%lld\n", ans.s[0] % g);
	return 0;
} 

  

猜你喜欢

转载自www.cnblogs.com/Memory-of-winter/p/9491857.html