結果
問題 |
No.3148 Min-Cost Destruction of Parentheses
|
ユーザー |
![]() |
提出日時 | 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; }