Arc of Dream HDU - 4686

原题链接

  • 题意:\(A_i = A_{i-1}\times A_x + A_y,B_i = B_{i-1}\times B_x + B_y\),给出\(A_0,B_0,A_x,B_x,A_y,B_y\)求,\(\sum ^{n-1}_{i = 0}A_i\times B_i\)\(0<=n<=1e18\)其余都小于 \(1e9\)
  • 题解:学会这种矩阵的构造方法,除了见多识广,别无他法。首先根据式子,$$A_i\times B_i = (A_{i-1}\times A_x +A_y)\times (B_{i-1}\times B_x + B_y)$$,然后继续推,$$A_i\times B_i = A_{i-1}\times A_x\times B_y + B_{i-1}\times B_x \times A_y + A_{i-1}\times A_x \times B_{i-1}\times B_x + A_y\times B_y$$

\(ANS\) 矩阵为\(\begin{bmatrix} ans& 0 & 0 & 0 &0 \\ A_i\times 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\)\(\begin{bmatrix} 1& 1& 0 & 0 &0 \\ 0& A_x\times B_x& A_x\times B_y& A_y\times B_x & A_y\times 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;
}
posted @ 2021-03-28 10:23  u_yan  阅读(39)  评论(0编辑  收藏  举报