結果
| 問題 |
No.3148 Min-Cost Destruction of Parentheses
|
| コンテスト | |
| ユーザー |
Nauclhlt🪷
|
| 提出日時 | 2025-05-12 00:02:49 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 59 ms / 4,000 ms |
| コード長 | 2,364 bytes |
| コンパイル時間 | 1,956 ms |
| コンパイル使用メモリ | 209,764 KB |
| 実行使用メモリ | 7,900 KB |
| 最終ジャッジ日時 | 2025-05-15 23:07:29 |
| 合計ジャッジ時間 | 3,946 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 31 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
int N;
vector<int> parents;
vector<long long> zeros;
vector<int> ones;
long long ans;
UnionFind(const vector<int>& A) {
N = A.size();
parents.assign(N, -1);
zeros = vector<long long>(A.begin(), A.end());
ones.assign(N, 1);
ans = 0;
}
int find(int x) {
if (parents[x] < 0) return x;
vector<int> st;
while (parents[x] >= 0) {
st.push_back(x);
x = parents[x];
}
for (int y : st) parents[y] = x;
return x;
}
void unite(int x, int y) {
x = find(x);
y = find(y);
if (x == y) return;
// x に y をマージ
parents[x] += parents[y];
parents[y] = x;
ans += ones[x] * zeros[y];
zeros[x] += zeros[y];
ones[x] += ones[y];
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
string S;
cin >> S;
// A[0] = 0, A[1..N] は入力
vector<int> A(N + 1);
A[0] = 0;
for (int i = 1; i <= N; ++i) {
cin >> A[i];
}
UnionFind uf(A);
// 木構造の親を構築
vector<int> stk = {0};
vector<int> parent(N + 1, -1);
int next_idx = 1;
for (int i = 0; i < 2 * N; ++i) {
if (S[i] == '(') {
parent[next_idx] = stk.back();
stk.push_back(next_idx++);
} else {
stk.pop_back();
}
}
// (比率, idx) の最小ヒープ
using P = pair<double,int>;
priority_queue<P, vector<P>, greater<P>> pq;
for (int i = 0; i <= N; ++i) {
// 初期値: -(zeros[i]/ones[i]) = -A[i]/1
pq.emplace(-(double)A[i], i);
}
while (!pq.empty()) {
auto [value, idx] = pq.top();
pq.pop();
// Python版と同じく "idx" に対してチェック
double current = -(double)uf.zeros[idx] / uf.ones[idx];
if (value != current) continue;
// union(parent[idx], idx)
uf.unite(parent[idx], idx);
// マージ後の代表元を取得
int head = uf.find(idx);
if (head != 0) {
double nw = -(double)uf.zeros[head] / uf.ones[head];
pq.emplace(nw, head);
}
}
cout << uf.ans << "\n";
return 0;
}
Nauclhlt🪷