結果
| 問題 |
No.1873 Bracket Swapping
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-03-17 18:35:39 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 285 ms / 2,000 ms |
| コード長 | 5,911 bytes |
| コンパイル時間 | 2,015 ms |
| コンパイル使用メモリ | 138,116 KB |
| 最終ジャッジ日時 | 2025-01-28 10:00:01 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 27 |
ソースコード
#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';
}