- 题意:(A_i = A_{i-1} imes A_x + A_y,B_i = B_{i-1} imes B_x + B_y),给出(A_0,B_0,A_x,B_x,A_y,B_y)求,(sum ^{n-1}_{i = 0}A_i imes B_i),(0<=n<=1e18)其余都小于 (1e9)。
- 题解:学会这种矩阵的构造方法,除了见多识广,别无他法。首先根据式子,$$A_i imes B_i = (A_{i-1} imes A_x +A_y) imes (B_{i-1} imes B_x + B_y)$$,然后继续推,$$A_i imes B_i = A_{i-1} imes A_x imes B_y + B_{i-1} imes B_x imes A_y + A_{i-1} imes A_x imes B_{i-1} imes B_x + A_y imes B_y$$
(ANS) 矩阵为(egin{bmatrix} ans& 0 & 0 & 0 &0 \ A_i imes B_i& 0& 0& 0 & 0\ A_i&0 & 0& 0&0 \ B_i&0 &0 &0 &0 \ 1& 0 & 0 & 0 & 0 end{bmatrix})然后就可以推出系数矩阵 (A) 为 (egin{bmatrix} 1& 1& 0 & 0 &0 \ 0& A_x imes B_x& A_x imes B_y& A_y imes B_x & A_y imes B_y\ 0&0 & A_x& 0&A_y \ 0&0 &0 &B_x &B_y \ 1& 0 & 0 & 0 & 1 end{bmatrix})
- 代码:
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const int N = 555;
const int NN = 5;
ll n;
struct Matrix {
ll a[NN][NN];
Matrix(){memset(a, 0, sizeof a);}
Matrix operator*(Matrix rhs)const {
Matrix ret;
for (int i = 0; i < NN; i ++) {
for (int j = 0; j < NN; j++) {
for (int k = 0; k < NN; k ++) {
(ret.a[i][j] += a[i][k] * rhs.a[k][j]%mod) %=mod;
}
}
}
return ret;
}
void pr() {
for (int i = 0; i < NN; i++) {
for (int j = 0; j < NN; j ++) {
cout << a[i][j] << " ";
}
cout << endl;
}
}
};
Matrix ksm(Matrix a, ll k) {
Matrix ret = a;
k--;
if (k <= 0)return ret;
while (k) {
if (k & 1)ret = ret * a;
k >>= 1;
a = a * a;
}
return ret;
}
void solve() {
while (cin >> n) {
Matrix A, ans;
ll AX, BX, AY, BY, A0, B0;
cin >> A0 >> AX >> AY >> B0 >> BX >> BY;
A0%=mod;
AX%=mod;
AY%=mod;
BX%=mod;
BY%=mod;
B0%=mod;
ll AXBX = AX * BX % mod;
ll AXBY = AX * BY % mod;
ll AYBX = AY * BX % mod;
ll AYBY= AY*BY%mod;
ll t[NN][NN] = {
{1, 1, 0, 0, 0},
{0, AXBX, AXBY, AYBX, AYBY},
{0, 0, AX, 0, AY},
{0, 0, 0, BX, BY},
{0, 0, 0, 0, 1},
};
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++)A.a[i][j] = t[i][j];
}
ll tt[NN][NN] = {
{0},
{A0*B0%mod},
{A0},
{B0},
{1},
};
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++)ans.a[i][j] = tt[i][j];
}
if (n <= 0) {
cout << 0 << endl;
} else
if (n == 1) {
cout << A0 * B0 % mod << endl;
} else {
A = ksm(A, n);
ans = A * ans;
cout << ans.a[0][0] << endl;
}
}
}
int main()
{
ios::sync_with_stdio(0);
int t = 1;//cin >>t;
while (t--)
solve();return 0;
}