結果
問題 | No.569 3 x N グリッドのパスの数 |
ユーザー |
![]() |
提出日時 | 2019-08-20 18:05:40 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 3 ms / 2,000 ms |
コード長 | 3,090 bytes |
コンパイル時間 | 1,017 ms |
コンパイル使用メモリ | 81,848 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-10-06 12:41:42 |
合計ジャッジ時間 | 3,101 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 60 |
ソースコード
#include <algorithm> #include <iostream> #include <vector> using namespace std; //----------------------- const int MOD = (int)1e9 + 7; struct mint { int n; mint(int n = 0) : n(n) { } }; mint operator+(mint a, mint b) { return (a.n += b.n) >= MOD ? a.n - MOD : a.n; } mint operator-(mint a, mint b) { return (a.n -= b.n) < 0 ? a.n + MOD : a.n; } mint operator*(mint a, mint b) { return 1LL * a.n * b.n % MOD; } mint &operator+=(mint &a, mint b) { return a = a + b; } mint &operator-=(mint &a, mint b) { return a = a - b; } mint &operator*=(mint &a, mint b) { return a = a * b; } ostream &operator<<(ostream &os, mint a) { return os << a.n; } istream &operator>>(istream &is, mint& a) { return is >> a.n; } mint operator^(mint a, long long n) { mint r = 1; while (n) { if (n & 1) r *= a; a *= a; n >>= 1; } return r; } mint inv(mint x) { long long a = x.n, b = MOD, u = 1, v = 0; while (b) { long long t = a/b; swap((a -= t*b), b); swap((u -= t*v), v); } return mint(u); } //----------------------- template<class T> ostream& operator<<(ostream& os, const vector<T>& vec) { for (auto &vi: vec) os << vi << " "; return os; } template<class T> struct Matrix { vector<vector<T>> val; Matrix(int n = 1, int m = 1, T x = 0) { val.assign(n, vector<T>(m, x)); } size_t size() const { return val.size(); } vector<T>& operator[](int i) { return val[i]; } const vector<T>& operator[](int i) const { return val[i]; } friend ostream& operator<<(ostream& os, const Matrix<T> M) { for (int i = 0; i < M.size(); ++i) os << M[i] << " \n"[i != M.size() - 1]; return os; } }; template<class T> Matrix<T> operator^(Matrix<T> A, long long n) { Matrix<T> R(A.size(), A.size()); for (int i = 0; i < A.size(); ++i) R[i][i] = 1; while (n > 0) { if (n & 1) R = R * A; A = A * A; n >>= 1; } return R; } template<class T> Matrix<T> operator*(const Matrix<T>& A, const Matrix<T>& B) { Matrix<T> R(A.size(), B[0].size()); for (int i = 0; i < A.size(); ++i) for (int j = 0; j < B[0].size(); ++j) for (int k = 0; k < B.size(); ++k) R[i][j] += A[i][k] * B[k][j]; return R; } template<class T> vector<T> operator*(const Matrix<T> &A, vector<T> &B) { vector<T> v(A.size()); for (int i = 0; i < A.size(); ++i) for (int k = 0; k < B.size(); ++k) v[i] += A[i][k] * B[k]; return v; } const int SZ = 12; string M[SZ] = { "111100001111", "111100000011", "111111000000", "111111110000", "100011000000", "100011100000", "110001110000", "110000110000", "001100001100", "001100001110", "000100000111", "000100000011", }; #include <cassert> int main() { long long N; cin >> N; Matrix<mint> trans(SZ, SZ); for (int i = 0; i < SZ; i++) for (int j = 0; j < SZ; j++) { trans[i][j] = M[i][j] - '0'; } vector<mint> state(SZ); state[0] = 1; auto final = (trans ^ N) * state; mint ans = 0; for (int i = 0; i < 8; i++) ans += final[i]; cout << ans << endl; assert(ans.n == (((trans ^ (N + 1)) * state)[3]).n); return 0; }