传送门
题意
数列$X_{n+1}=(aX_n+c)\bmod m$
其中$a,c$是给定的常数,$n>0$。$X_0$的值已给出。
然后呢,你需要求出$X_n\bmod 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\bmod m\bmod g\not=a\bmod \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;
}