洛谷 P2044 [NOI2012]随机数生成器
思路
首先,题目中直接给出了递推式,但按照题意直接做肯定是不行的,因为 \(n\) 很大,所以要用矩阵加速,初状态为 \([x_i \ c]\),末状态为 \([x_{i+1} \ c]\),转移矩阵为
\[\begin{bmatrix}x_i&c\end{bmatrix} \times \begin{bmatrix}a&0\\1&1\end{bmatrix}=\begin{bmatrix}x_{i+1}&c\end{bmatrix}
\]
注意 \(m\) 很大,做乘法的时候要用快速乘
代码
/*
Name: P2044 [NOI2012]随机数生成器
Author: Loceaner
Date: 02/09/20 15:01
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
const int A = 1e5 + 11;
const int B = 1e6 + 11;
const int inf = 0x3f3f3f3f;
inline int read() {
char c = getchar();
int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int mod, a, c, x0, n, g;
struct matrix {
int ma[3][3];
void init() { for (int i = 1; i <= 2; i++) ma[i][i] = 1; }
void clear() { memset(ma, 0, sizeof(ma)); }
} base, ans;
inline int mul(int a, int b) {
int res = 0;
while (b) {
if (b & 1) res = (res + a) % mod;
a = (a + a) % mod, b >>= 1;
}
return res;
}
matrix operator * (const matrix &a, const matrix &b) {
matrix c;
c.clear();
for (int k = 1; k <= 2; k++)
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 2; j++)
c.ma[i][j] = (c.ma[i][j] + mul(a.ma[i][k], b.ma[k][j])) % mod;
return c;
}
inline void power(int b) {
while (b) {
if (b & 1) ans = ans * base;
base = base * base, b >>= 1;
}
}
signed main() {
mod = read(), a = read(), c = read();
x0 = read(), n = read(), g = read();
ans.clear(), base.clear();
ans.ma[1][1] = x0, ans.ma[1][2] = c;
base.ma[1][1] = a, base.ma[1][2] = 0, base.ma[2][1] = 1, base.ma[2][2] = 1;
power(n);
cout << ans.ma[1][1] % g << '\n';
return 0;
}
转载不必联系作者,但请声明出处