BZOJ 3583: JJ female friends

The answer is \ (\ sum \ limits_ {i
= 0} ^ d (OI ^ T) ^ i [u] [v] \) may be \ (O \) in \ (v \ to 0 \) and \ (0 \ to 0 \) and \ (\) I in \ (0 \ to 0 \) are set to \ (1 \) , \ (d + 1 \) raised to the power of \ (u \ to 0 \) is the former \ (D \) matrix \ (u \ to v \) is the number of the program
to do so is the complexity of the \ (O (mn ^ 3 \ log d) \) , and not over
it is noted that \ ((OI ^ T) ^ {d + 1}
= O (I ^ tO) ^ d I ^ T \) such complexity is \ (O (mk ^ 3 \ log d) \) , the problem is solved.
There will do matrix multiplication modulo a lot of times, you can save it as long long, larger than \ (2 ^ 60 \) and then take the mold, faster than doubled. .

#include <bits/stdc++.h>
typedef long long ll;

const int N = 1007;
const int MOD = 1000000007;

inline void M(int &x) {
    if (x >= MOD) x -= MOD;
    if (x < 0) x += MOD;
}

struct Mat {
    int r, c;
    std::vector< std::vector<int> > mat;
    inline void init(int _r, int _c, int x = 0) {
        r = _r; c = _c;
        mat.resize(r + 1);
        for (int i = 0; i <= r; i++) {
            mat[i].resize(c + 1);
            for (int j = 0; j <= c; j++) {
                if (i == j) mat[i][j] = x;
                else mat[i][j] = 0;
            }
        }
    }
    inline Mat operator * (const Mat &p) const {
        static Mat res;
        res.init(r, p.c);
        for (int i = 0; i <= r; i++)
            for (int j = 0; j <= p.c; j++) {
                ll x = 0;
                for (int k = 0; k <= c; k++) {
                    x += 1LL * mat[i][k] * p.mat[k][j];
                    if (x >= (1LL << 60))
                        x %= MOD;
                }
                res.mat[i][j] = x % MOD;
            }
        return res;
    }
} O, I;

int n, k;

inline Mat qp(Mat a, int b) {
    static Mat res;
    res.init(a.r, a.c, 1);
    while (b) {
        if (b & 1) res = res * a;
        a = a * a;
        b >>= 1;
    }
    return res;
}

int main() {
    scanf("%d%d", &n, &k);
    O.init(n, k); I.init(k, n);
    for (int i = 1, x; i <= n; i++) {
        for (int j = 1; j <= k; j++) {
            scanf("%d", &x);
            M(O.mat[i][j] = x);
        }
        for (int j = 1; j <= k; j++) {
            scanf("%d", &x);
            M(I.mat[j][i] = x);
        }
    }
    int m;
    scanf("%d", &m);
    while (m--) {
        int u, v, d;
        scanf("%d%d%d", &u, &v, &d);
        O.mat[v][0] = O.mat[0][0] = I.mat[0][0] = 1;
        static Mat res;
        res = (I * O);
        res = O * qp(res, d);
        int ans = 1LL * res.mat[u][0] * I.mat[0][0] % MOD;
        printf("%d\n", ans);
        O.mat[v][0] = O.mat[0][0] = I.mat[0][0] = 0;
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Mrzdtz220/p/12293949.html
JJ