矩阵快速幂
ai = ai-1 * Ax + Ay;
bi = bi-1 * Bx + By;
ai * bi = ai-1 * bi-1 * (Ax * Bx) + ai-1 * (Ax * By) + bi-1 * (Bx * Ay) + AyBy;
Si = Si - 1 + ai * bi = Si - 1 + ai-1 * bi-1 * (Ax * Bx) + ai-1 * (Ax * By) + bi-1 * (Bx * Ay) + AyBy;
根据SI , 一定需要 Si - 1, ai - 1, bi - 1, ai - 1 * bi - 1, 常数。
矩阵大小为5,
构造 初始矩阵A 为 记 S0
[1, A0, B0, A0 * B0, A0 * B0] 即 [1, a0, b0, a0 * b0, S0]
[0 …… 0]
转换矩阵 B. 使得 A * B = S1 = [1, a1, b1, a1 * b1 , S1]
根据上面4个公式得。
第一列为 1, 0, 0, 0, 0;
第二列为 Ay, Ax, 0, 0, 0;
第三列为 By, 0, Bx, 0, 0;
第四列为 AyBy, Ax * By, Bx * Ay, Ax * Bx, 0;
第五列为 AyBy, Ax * By, Bx * Ay, Ax * Bx, 1;
即
N次递推得
现在要求 Sn - 1 , 所以 init * Pow ^ n - 1. 然后取第一行, 第5个元素。
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int V = 100000 + 50;
- const int mod = 1000000000 + 7;
- const int MaxN = 5;
- struct Matrix{
- __int64 mat[MaxN][MaxN];
- };
- Matrix init, Pow;
- __int64 n, A0, Ax, Ay, B0, Bx, By;
- Matrix multi(Matrix a, Matrix b) {
- Matrix ans;
- for(int i = 0; i < MaxN; ++i)
- for(int j = 0; j < MaxN; ++j) {
- __int64 sum = 0;
- for(int k = 0; k < MaxN; ++k)
- sum = (sum + a.mat[i][k] * b.mat[k][j] % mod) % mod;
- ans.mat[i][j] = sum;
- }
- return ans;
- }
- Matrix MatrixQuickPow(Matrix a, __int64 b) {
- Matrix ans = init;
- while(b) {
- if(b & 1)
- ans = multi(ans, a);
- b /= 2;
- a = multi(a, a);
- }
- return ans;
- }
- int main() {
- while(~scanf("%I64d", &n)) {
- scanf("%I64d%I64d%I64d%I64d%I64d%I64d", &A0, &Ax, &Ay, &B0, &Bx, &By);
- if(!n) {
- printf("0\n");
- continue;
- }
- init.mat[0][0] = 1;
- init.mat[0][1] = A0;
- init.mat[0][2] = B0;
- init.mat[0][3] = init.mat[0][4] = A0 * B0 % mod;
- Pow.mat[0][0] = Pow.mat[4][4] = 1;
- Pow.mat[0][1] = Ay;
- Pow.mat[0][2] = By;
- Pow.mat[0][3] = Pow.mat[0][4] = Ay * By % mod;
- Pow.mat[1][1] = Ax;
- Pow.mat[2][2] = Bx;
- Pow.mat[1][3] = Pow.mat[1][4] = Ax * By % mod;
- Pow.mat[2][3] = Pow.mat[2][4] = Ay * Bx % mod;
- Pow.mat[3][3] = Pow.mat[3][4] = Ax * Bx % mod;
-
-
-
-
-
-
- Matrix ans = MatrixQuickPow(Pow, n - 1);
- printf("%I64d\n", ans.mat[0][4]);
- }
- }