Trails (Medium)§
首先我们继承Trails (Easy)的整体思路。
我们发现n的范围很大,同时观察Trails (Easy)的更新状态过程。
可以考虑用矩阵快速幂,对于每一天的(矩阵)dp,我们都可以由(矩阵)dp*cnt(前一天)得到,化简得dp = dp*((cnt)^n)。
这里的dp是一个二维数组,和Trails (Easy)中的不同。第一维大小为1,第二维大小为m。这是为了方便矩阵乘法。
最后求和即可。
#include <bits/stdc++.h> #define all(a) a.begin(), a.end() #define int long long #define PII pair<int, int> using ll = long long; const int N = 1e5 + 10, INF = 0x3f3f3f3fll, MOD = 1e9 + 7; using namespace std; class Mat { int rows, columns, _MOD = 1e9 + 7; vector<vector<int>> matrix; public: Mat(int rows, int columns) : rows(rows), columns(columns) { matrix = vector<vector<int>>(rows, vector<int>(columns, 0)); } Mat(vector<vector<int>> matrix) : matrix(matrix) { rows = matrix.size(), columns = matrix[0].size(); } Mat get_Z() { return Mat(rows, columns); } Mat get_E() { Mat Z = get_Z(); for (int i = 0; i < rows; i++) Z[i][i] = 1; return Z; } vector<int> &operator[](int index) { return matrix[index]; } const vector<int> &operator[](int index) const { return matrix[index]; } Mat operator*(const Mat &other) { int _rows = rows, _columns = other.columns; Mat _matrix(_rows, _columns); for (int i = 0; i < _rows; i++) for (int j = 0; j < _columns; j++) for (int k = 0; k < columns; k++) _matrix[i][j] = (_matrix[i][j] + matrix[i][k] * other[k][j] % _MOD) % _MOD; return _matrix; } Mat pow(int n) { Mat result = get_E(), base = *this; while (n) { if (n & 1) result = result * base; base = base * base; n >>= 1; } return result; } }; void solve() { int m, n; cin >> m >> n; vector<int> s(m), l(m); for (int i = 0; i < m; i++) cin >> s[i]; for (int i = 0; i < m; i++) cin >> l[i]; Mat dp(1, m), cnt(m, m); dp[0][0] = 1; for (int i = 0; i < m; i++) for (int j = 0; j < m; j++) cnt[i][j] = cnt[j][i] = (s[i] * s[j] + s[i] * l[j] + l[i] * s[j]) % MOD; dp = dp * cnt.pow(n); cout << accumulate(all(dp[0]), 0ll) % MOD << '\n'; } signed main() { ios::sync_with_stdio(0), cin.tie(0); int T = 1; // cin >> T, cin.get(); while (T--) solve(); return 0; }