CF678D 题解
前置芝士:矩阵乘法。
线性递推式:$ g^{n}(x) = Ag^{n - 1}(x) + B $。
那么,可以列出以下式子:
\[\begin{bmatrix} g^n(x) \\ B \end{bmatrix} = \textbf{A}\begin{bmatrix} g^{n - 1}(x) \\ B \end{bmatrix}
\]
解得转置矩阵 $ \textbf{A} $ :
\[\textbf{A} = \begin{bmatrix} A & 1 \\ 0 & 1 \end{bmatrix}
\]
所以:
\[\begin{bmatrix} g^n(x) \\ B \end{bmatrix} = \textbf{A}^{n}\begin{bmatrix} g^{0}(x) \\ B \end{bmatrix} = \textbf{A}^{n}\begin{bmatrix} x \\ B \end{bmatrix}
\]
奉上码风清奇代码一份:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int m = 1e9 + 7;
ll a, b, n, L = 2, x;
inline ll read() {
ll x = 0;
bool f = true;
char c = getchar();
while (!isdigit(c)) {
if (c == '-')
f = false;
c = getchar();
}
while (isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
return f ? x : -x;
}
struct Matrix {
ll M[3][3];
void clear() memset(M, 0, sizeof(M));
void reset() {
clear();
for (int i = 0; i < L; i++)
M[i][i] = 1;
}
Matrix friend operator* (const Matrix &a, const Matrix &b) {
Matrix Ans;
Ans.clear();
for (int i = 0; i < L; i++)
for (int j = 0; j < L; j++)
for (int k = 0; k < L; k++)
Ans.M[i][j] = (Ans.M[i][j] + a.M[i][k] * b.M[k][j]) % m;
return Ans;
}
};
Matrix qp(Matrix a, ll p) {
Matrix Ans;
Ans.reset();
while (p) {
if (p & 1)
Ans = Ans * a;
a = a * a;
p >>= 1;
}
return Ans;
}
int main() {
a = read();
b = read();
n = read();
x = read();
Matrix A;
A.M[0][0] = a, A.M[0][1] = 1;
A.M[1][0] = 0, A.M[1][1] = 1;
A = qp(A, n);
cout << (A.M[0][0] * x + A.M[0][1] * b) % m;
return 0;
}
双倍经验:P2044 随机数生成器

浙公网安备 33010602011771号