CF678D Iterated Linear Function
题意
\(f_{i,x}=A\times f_{i-1,x} + B\) 且 \(f_{0,x}=x\) 求 \(f_{n,x}\)。
思路
这道题的递推关系十分清晰。但由于数据范围大(\(1\le A,B,x\le 10^ 9,1\le n \le 10^{18}\)),所以这道题只能使用矩阵乘法加速递推。
矩阵的构造
我们需要构造一个矩阵 \(P\),使得 \(\begin{bmatrix} f_{0,x}& b\\ 0&0 \end{bmatrix}\times P= \begin{bmatrix} f_{1,x}&b\\ 0&0 \end{bmatrix}\)。根据矩阵乘法的规则,我们可以很容易地推出 \(P=\begin{bmatrix} A&0\\ 1&1\end{bmatrix}\)。由于 \(f_{0,x}=x\),所以要得到 \(f_{n,x}\) 就可以转化为求 \(\begin{bmatrix} x& b\\ 0&0 \end{bmatrix}\times P^n = \begin{bmatrix} f_{n,x}&b\\ 0&0 \end{bmatrix}\),使用矩阵快速幂解决。
code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9 + 7;
int m, n, x, y, a, b;
struct arr {
int a[15][15];
arr() {memset(a, 0, sizeof a);}
arr operator*(const arr& B) const {//重载乘法
arr cur;
int r;
for (int i = 1; i <= 2; ++i)
for (int k = 1; k <= 2; ++k) {
r = a[i][k];
for (int j = 1; j <= 2; ++j)
cur.a[i][j] += B.a[k][j] * r, cur.a[i][j] %= mod;
}
return cur;
}
arr operator^(int x) const {//重载快速幂
arr cur, res;
for (int i = 1; i <= 2; ++i) cur.a[i][i] = 1;
for (int i = 1; i <= 2; ++i)
for (int j = 1; j <= 2; ++j) res.a[i][j] = a[i][j] % mod;
while (x) {
if (x & 1) cur = cur * res;
res = res * res;
x >>= 1;
}
return cur;
}
} A, F;//A对应上文中的P矩阵,F为答案矩阵
int mode(int x, int m) {return (x + m) % m;}
void init() {//初始化
A.a[1][1] = a, A.a[1][2] = 0;
A.a[2][1] = 1, A.a[2][2] = 1;
F.a[1][1] = x, F.a[1][2] = b;
F = F * (A ^ n);
}
signed main() {
scanf("%lld%lld", &a, &b);
scanf("%lld", &n);
scanf("%lld", &x);
init();
printf("%lld", mode(F.a[1][1], mod));
return 0;
}
标签:Function,arr,end,Linear,int,矩阵,begin,Iterated,bmatrix
From: https://www.cnblogs.com/Ice-lift/p/17963441