結果
問題 | No.1873 Bracket Swapping |
ユーザー | yudedako |
提出日時 | 2022-03-17 18:35:39 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 262 ms / 2,000 ms |
コード長 | 5,911 bytes |
コンパイル時間 | 1,607 ms |
コンパイル使用メモリ | 143,360 KB |
実行使用メモリ | 20,608 KB |
最終ジャッジ日時 | 2024-10-01 15:24:08 |
合計ジャッジ時間 | 4,932 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,820 KB |
testcase_01 | AC | 2 ms
6,816 KB |
testcase_02 | AC | 2 ms
6,820 KB |
testcase_03 | AC | 24 ms
6,816 KB |
testcase_04 | AC | 10 ms
6,820 KB |
testcase_05 | AC | 9 ms
6,820 KB |
testcase_06 | AC | 104 ms
11,776 KB |
testcase_07 | AC | 2 ms
6,816 KB |
testcase_08 | AC | 195 ms
19,200 KB |
testcase_09 | AC | 197 ms
20,480 KB |
testcase_10 | AC | 147 ms
16,000 KB |
testcase_11 | AC | 2 ms
6,816 KB |
testcase_12 | AC | 79 ms
10,368 KB |
testcase_13 | AC | 64 ms
9,088 KB |
testcase_14 | AC | 187 ms
18,560 KB |
testcase_15 | AC | 40 ms
6,912 KB |
testcase_16 | AC | 2 ms
6,816 KB |
testcase_17 | AC | 99 ms
13,568 KB |
testcase_18 | AC | 3 ms
6,816 KB |
testcase_19 | AC | 7 ms
6,816 KB |
testcase_20 | AC | 160 ms
16,384 KB |
testcase_21 | AC | 3 ms
6,816 KB |
testcase_22 | AC | 13 ms
6,816 KB |
testcase_23 | AC | 262 ms
20,608 KB |
testcase_24 | AC | 181 ms
20,480 KB |
testcase_25 | AC | 207 ms
20,480 KB |
testcase_26 | AC | 103 ms
13,312 KB |
testcase_27 | AC | 146 ms
17,664 KB |
testcase_28 | AC | 22 ms
20,096 KB |
testcase_29 | AC | 2 ms
6,816 KB |
ソースコード
#include <iostream> #include <unordered_map> #include <unordered_set> #include <set> #include <vector> #include <numeric> #include <algorithm> #include <queue> #include <string> #include <random> #include <array> #include <climits> #include <map> #include <cassert> #include <stack> #include <iomanip> #include <cfloat> #include <bitset> #include <fstream> #include <chrono> constexpr int MOD = 998244353; template<int MOD = 998244353> class ModInt { long long int raw_value; static long long int inverse(const long long int value) { long long int x = value, y = MOD, a = 1, b = 0, c = 0, d = 1; while (y != 0) { const auto q = x / y; const auto e = a - c * q; const auto f = b - d * q; a = c; b = d; c = e; d = f; x = y; y = c * value - d * MOD; } assert(std::abs(x) == 1LL); return x == 1 ? a % MOD : -a % MOD; } public: ModInt() : raw_value{ 0 } {}; ModInt(const int value) : raw_value{ value } {}; ModInt(const long long int value) : raw_value{ value % MOD } {}; ModInt<MOD> operator+(const ModInt<MOD> right) const { return raw_value + right.raw_value; } ModInt<MOD>& operator+=(const ModInt<MOD> right) { return *this = *this + right; } ModInt<MOD> operator-(const ModInt<MOD> right) const { return raw_value - right.raw_value; } ModInt<MOD>& operator-=(const ModInt<MOD> right) { return *this = *this - right; } ModInt<MOD> operator*(const ModInt<MOD> right) const { return raw_value * right.raw_value; } ModInt<MOD>& operator*=(const ModInt<MOD> right) const { return *this = *this * right; } ModInt<MOD> operator/(const ModInt<MOD> right) const { return raw_value * inverse(right.raw_value); } ModInt<MOD> operator/=(const ModInt<MOD> right) { return *this = *this / right; } ModInt<MOD> pow(long long int exp) const { ModInt result(1), base{ *this }; while (exp > 0) { if ((exp & 1) == 1) { result *= base; } base *= base; exp >>= 1; } return result; } long long int value() const { return (raw_value + MOD) % MOD; } }; template<int MOD> std::ostream& operator<<(std::ostream& os, const ModInt<MOD>& mint) { return os << (mint.value() + MOD) % MOD; } template<typename T> class Matrix { std::vector<std::vector<T>> vec; int _row, _column; public: int row() const { return _row; } int column() const { return _column; } static Matrix<T> E(const int size) { Matrix<T> result(size, size); for (auto i = 0; i < size; ++i) { result[i][i] = 1; } return result; } Matrix(const int row, const int column) : vec(row, std::vector<T>(column)), _row{ row }, _column{ column } {}; Matrix(Matrix<T>&& other) = default; Matrix(const Matrix<T> & other) = default; Matrix<T>& operator=(Matrix<T> &&other) = default; Matrix<T>& operator=(const Matrix<T> & other) = default; const std::vector<T>& operator[](const int index) const { return vec[index]; } std::vector<T>& operator[](const int index) { return vec[index]; } Matrix<T> operator*(const Matrix<T>& right) const { const int row = this->row(); const int mid = this->column(); const int column = right.column(); Matrix result(row, column); for (auto i = 0; i < row; ++i) { for (auto j = 0; j < column; ++j) { T value = vec[i][0] * right.vec[0][j]; for (auto k = 1; k < mid; ++k) { value += vec[i][k] * right.vec[k][j]; } result[i][j] = value; } } return result; } Matrix<T>& operator*=(const Matrix<T>& right) { return *this = *this * right; } Matrix<T> pow(long long int exp) const { auto result = Matrix<T>::E(row()); auto base = *this; while (exp > 0) { if ((exp & 1) == 1) { result *= base; } base *= base; exp >>= 1; } return result; } }; template<typename T> std::ostream& operator<<(std::ostream& os, const Matrix<T>& matrix) { for (auto i = 0; i < matrix.row(); ++i) { os << '['; for (auto j = 0; j < matrix.column(); ++j) { if (j > 0) { os << ", "; } os << matrix[i][j]; } os << "]\n"; } return os; } Matrix<ModInt<MOD>> make_matrix(const int size) { const int half = size / 2; Matrix<ModInt<MOD>> result(half + 1, half + 1); for (auto i = 0; i <= half; ++i) { if (0 <= i - 1) { result[i][i - 1] = (half - i + 1) * (half - i + 1); } result[i][i] = (half - i) * (half - i - 1) + i * (i - 1) + 2 * (size - 2 * i) * i; if (i + 1 <= half) { result[i][i + 1] = (i + 1) * (i + 1); } } return result; } template<typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) { os << "["; for (auto i = 0; i < vec.size(); ++i) { if (i > 0) { os << ", "; } os << vec[i]; } return os << "]"; } int main() { std::string str; std::cin >> str; int k; std::cin >> k; const int size = str.size(); const int half = size / 2; std::vector<std::vector<std::vector<ModInt<MOD>>>> memo(size + 1, std::vector<std::vector<ModInt<MOD>>>(half + 1, std::vector<ModInt<MOD>>(half + 1))); memo[0][0][0] = 1; for (auto i = 0; i < size; ++i) { const auto c = str[i]; for (auto height = 0; height <= half; ++height) { for (auto to_right = 0; to_right <= half; ++to_right) { if (c == '(') { ModInt<MOD> pattern{ 0 }; if (0 <= height - 1) { pattern += memo[i][height - 1][to_right]; } if (height + 1 <= half && 0 < to_right) { pattern += memo[i][height + 1][to_right - 1]; } memo[i + 1][height][to_right] = pattern; } else { ModInt<MOD> pattern{ 0 }; if (height + 1 <= half) { pattern += memo[i][height + 1][to_right]; } if (0 <= height - 1) { pattern += memo[i][height - 1][to_right]; } memo[i + 1][height][to_right] = pattern; } } } } const auto matrix = make_matrix(size).pow(k); ModInt<MOD> result{ 0 }; for (auto to_right = 0; to_right <= half; ++to_right) { result += matrix[0][to_right] * memo[size][0][to_right]; } std::cout << result << '\n'; }