数列$X_{n+1}=(aX_n+c)\mod m$
其中$a,c$是给定的常数,$n>0$。$X_0$的值已给出。
然后呢,你需要求出$X_n\mod g$。
$n,m,a,c,X_0\leq10^{18},g\leq 10^8$。
构造列向量
$$C_n=\begin{bmatrix}1\\X_n\end{bmatrix}$$
然后,构造转移矩阵
$$\begin{bmatrix}1&0\\c&a\end{bmatrix}C_n=C_{n+1}$$
嗯。然后要注意的:
$$a\mod m\mod g\not=a\mod \min(m,g)$$。
所以要用到神奇的long long乘法。
嗯。贴代码:
#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
typedef array<array<ll, 3>, 3> Matrix;
ll P;
Matrix A, I;
 
inline ll MulMod(ll a, ll b, ll m){
	ll t = a * b - (ll)((long double)a * b / m + 1e-10) * m;
	return (t %= m) < 0 ? t + m : t;
}
Matrix MatrixMul(const Matrix &A, const Matrix &B) {
    Matrix ret;
    for (int i=1; i<=2; i++)
        for (int j=1; j<=2; j++) {
            ret[i][j] = 0;
            for (int k=1; k<=2; k++)
                (ret[i][j] += MulMod(A[i][k], B[k][j], P)) %= P;
        }
    return ret;
}
Matrix PowerMod(ll k) {
    if (k == 0) return I;
    if (k == 1) return A;
    if (k & 1) return MatrixMul(PowerMod(k-1), A);
    Matrix B = PowerMod(k >> 1);
    return MatrixMul(B, B);
}
 
signed main() {
    I[1][1] = I[2][2] = 1;
    ll m,a,c,x0,n,g;
    scanf("%lld%lld%lld%lld%lld%lld", &m,&a,&c,&x0,&n,&g);
    P = m;
    A[1][1] = 1; A[1][2] = 0; A[2][1] = c; A[2][2] = a;
	Matrix ret = PowerMod(n);
	ll ans = (MulMod(x0, ret[2][2], m) + ret[2][1]) % m % g;
	if (ans < 0) {
		ans = (ans + (-ans / g) * g + g) % g;
	}
    printf("%lld\n", ans);
    return 0;
}
原文:https://www.cnblogs.com/mchmch/p/9355875.html