結果
| 問題 |
No.3147 Parentheses Modification and Rotation (RM Ver.)
|
| コンテスト | |
| ユーザー |
Nauclhlt🪷
|
| 提出日時 | 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;
}
Nauclhlt🪷