题意:An Arc of Dream is a curve defined by following function:
where
a 0 = A0
a i = a i-1 * AX+AY
b 0 = B0
b i = b i-1 * BX+BY
给出n,A0,AX,AY,B0,BX,BY,What is the value of AoD(N) modulo 1,000,000,007?
题解:矩阵快速幂
数据范围很恶心,先要对原数据取模,对于两个数的乘法也要马上取模。
题目给出的转移关系很明确,由于要求和,可得转移矩阵为
T
=
[
A
X
0
A
Y
0
0
0
B
X
B
Y
0
0
0
0
1
0
0
A
X
∗
B
Y
B
X
∗
A
Y
A
Y
∗
B
Y
A
X
∗
B
X
0
A
X
∗
B
Y
B
X
∗
A
Y
A
Y
∗
B
Y
A
X
∗
B
X
1
]
T= \left[ \begin{matrix} AX & 0 & AY&0&0 \\ 0 & BX & BY&0&0 \\ 0&0&1&0&0\\ AX*BY&BX*AY&AY*BY&AX*BX&0\\ AX*BY&BX*AY&AY*BY&AX*BX&1\\ \end{matrix} \right]
T=⎣⎢⎢⎢⎢⎡AX00AX∗BYAX∗BY0BX0BX∗AYBX∗AYAYBY1AY∗BYAY∗BY000AX∗BXAX∗BX00001⎦⎥⎥⎥⎥⎤
初始矩阵为
m
a
=
[
A
0
(
a
i
−
1
)
B
0
(
b
i
−
1
)
1
A
0
∗
B
0
(
(
a
i
−
1
)
∗
(
b
i
−
1
)
)
A
0
∗
B
0
(
A
o
D
)
]
ma= \left[ \begin{matrix} A0(a_{i-1}) \\ B0(b_{i-1}) \\ 1 \\ A0*B0((a_{i-1})*(b_{i-1}))\\ A0*B0(AoD)\\ \end{matrix} \right]
ma=⎣⎢⎢⎢⎢⎡A0(ai−1)B0(bi−1)1A0∗B0((ai−1)∗(bi−1))A0∗B0(AoD)⎦⎥⎥⎥⎥⎤
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
//矩阵快速幂
const int mod = 1e9 + 7;
struct matrix {
ll mat[5][5];
matrix() { memset(mat, 0, sizeof(mat)); }
matrix operator * (const matrix& b)const {
matrix ans;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
ans.mat[i][j] = 0;
for (int k = 0; k < 5; k++) {
ans.mat[i][j] = (ans.mat[i][j] + mat[i][k] * b.mat[k][j] % mod + mod) % mod;
}
}
}
return ans;
}
};
matrix q_pow(matrix a, ll b) {
matrix ans;
memset(ans.mat, 0, sizeof(ans.mat));
for (int i = 0; i < 5; i++) ans.mat[i][i] = 1;
while (b) {
if (b & 1) ans = ans * a;
b >>= 1;
a = a * a;
}
return ans;
}
ll n, a0, ax, ay, b0, bx, by;
int main() {
while (~scanf("%lld%lld%lld%lld%lld%lld%lld", &n, &a0, &ax, &ay, &b0, &bx, &by)) {
a0 %= mod, ax %= mod, ay %= mod, b0 %= mod, bx %= mod, by %= mod;
if (n == 0) {
puts("0");
}
else if (n == 1) {
printf("%lld\n", a0 * b0 % mod);
}
else {
matrix ma;
ma.mat[0][0] = ax % mod, ma.mat[0][2] = ay % mod;
ma.mat[1][1] = bx % mod, ma.mat[1][2] = by % mod;
ma.mat[2][2] = 1;
ma.mat[3][0] = ax * by % mod, ma.mat[3][1] = bx * ay % mod, ma.mat[3][2] = ay * by % mod, ma.mat[3][3] = ax * bx % mod;
ma.mat[4][0] = ax * by % mod, ma.mat[4][1] = bx * ay % mod, ma.mat[4][2] = ay * by % mod, ma.mat[4][3] = ax * bx % mod, ma.mat[4][4] = 1;
ma = q_pow(ma, n - 1);
ll ans = ma.mat[4][0] * a0 % mod + ma.mat[4][1] * b0 % mod + ma.mat[4][2] + ma.mat[4][3] * (a0 * b0 % mod) % mod + a0 * b0 % mod;
printf("%lld\n", ans % mod);
}
}
return 0;
}