結果
問題 |
No.3147 Parentheses Modification and Rotation (RM Ver.)
|
ユーザー |
![]() |
提出日時 | 2025-05-15 19:25:58 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 21 ms / 2,000 ms |
コード長 | 3,586 bytes |
コンパイル時間 | 3,830 ms |
コンパイル使用メモリ | 229,384 KB |
実行使用メモリ | 7,848 KB |
最終ジャッジ日時 | 2025-05-15 19:26:04 |
合計ジャッジ時間 | 5,017 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 33 |
ソースコード
#include <bits/stdc++.h> #include <atcoder/convolution> using namespace std; using ll = long long; template<typename T, T OP(T, T), T APPLY(T, T)> class SegmentTree { private: int _treeSize; int _dataSize; int _originalDataSize; vector<T> _data; T _identity; public: SegmentTree(int n, T identity) { _originalDataSize = n; _identity = identity; int size = 1; while (n > size) { size <<= 1; } _dataSize = size; _treeSize = 2 * size - 1; _data.resize(_treeSize, _identity); } int OriginalDataSize() { return _originalDataSize; } int TreeSize() { return _treeSize; } T Identity() { return _identity; } void Build(vector<T>& array) { if (_originalDataSize != (int)array.size()) { throw exception(); } for (int i = 0; i < (int)array.size(); i++) { _data[i + _dataSize - 1] = array[i]; } for (int i = _dataSize - 2; i >= 0; i--) { _data[i] = OP(_data[(i << 1) + 1], _data[(i << 1) + 2]); } } void Apply(int index, T value) { index += _dataSize - 1; _data[index] = APPLY(_data[index], value); while (index > 0) { index = (index - 1) >> 1; _data[index] = OP(_data[(index << 1) + 1], _data[(index << 1) + 2]); } } T Query(int left, int right) { return QueryRec(left, right, 0, 0, _dataSize); } const T& operator[](size_t index) const { return _data[_dataSize - 1 + index]; } T& operator[](size_t index) { return _data[_dataSize - 1 + index]; } private: T QueryRec(int left, int right, int index, int l, int r) { if (left >= r || right <= l) { return _identity; } if (left <= l && r <= right) { return _data[index]; } return OP(QueryRec(left, right, (index << 1) + 1, l, (l + r) / 2), QueryRec(left, right, (index << 1) + 2, (l + r) / 2, r)); } }; int apply(int x, int a) { return a; } int op(int x, int y) { return min(x, y); } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); int N; cin >> N; string S; cin >> S; long R; long M; cin >> R >> M; if (N % 2 == 1) { cout << "-1" << endl; return 0; } int cl = 0; int cr = 0; for (int i = 0; i < N; i++) { if (S[i] == '(') cl++; else cr++; } int diff = abs(cl - cr) / 2; vector<int> src(2 * N); src[0] = S[0] == '(' ? 1 : -1; for (int i = 1; i < N; i++) { src[i] = src[i - 1] + (S[i] == '(' ? 1 : -1); } for (int i = 0; i < N; i++) { src[N + i] = src[N + i - 1] + (S[i] == '(' ? 1 : -1); } SegmentTree<int, op, apply> seg(2 * N, 10000000); seg.Build(src); long ans = numeric_limits<ll>::max(); for (int i = 0; i < N; i++) { int left = i == 0 ? 0 : src[i - 1]; int right = src[i + N - 1] - left; int mn = min(0, right); int m = seg.Query(i, i + N) - left; if (m < 0) { long cost = ((N - i) % N) * R + (diff + (mn - m + 1) / 2L * 2L) * M; ans = min(ans, cost); } else { long cost = ((N - i) % N) * R + diff * M; ans = min(ans, cost); } } cout << ans << endl; }