結果
問題 |
No.3148 Min-Cost Destruction of Parentheses
|
ユーザー |
![]() |
提出日時 | 2025-06-02 01:50:41 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 69 ms / 4,000 ms |
コード長 | 3,247 bytes |
コンパイル時間 | 1,246 ms |
コンパイル使用メモリ | 85,840 KB |
実行使用メモリ | 10,876 KB |
最終ジャッジ日時 | 2025-06-02 01:50:46 |
合計ジャッジ時間 | 3,675 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 31 |
ソースコード
#include <iostream> #include <vector> using namespace std; struct UF{ vector<int> par,sz; // 連結成分の親 vector<int> cp_par; vector<vector<int>> mergeTree; UF(int n, bool useMergeTree = false){ sz.resize(n); par.resize(n); cp_par.resize(n); for(int i=0;i<n;i++) sz[i] = 1, par[i] = i,cp_par[i] = i; if(useMergeTree){ sz.resize(2*n); par.resize(2*n); for(int i=n;i<2*n;i++) sz[i] = 1, par[i] = i; mergeTree.resize(2*n); } } int find(int x){ if(par[x]==x) return x; return par[x] = find(par[x]); } void unite(int x,int y){ x = find(x); y = find(y); if(x==y) return; if(sz[x]>sz[y]) swap(x,y); sz[y] += sz[x]; par[x] = y; cp_par[y] = same(cp_par[y],y) ? cp_par[x] : cp_par[y]; } bool same(int x,int y){return find(x)==find(y);} void merge(int child,int parent){ //parentが親,merge過程を表す木などで使用 child = find(child); parent = find(parent); if(child==parent) return; mergeTree[parent].push_back(child); sz[parent] += sz[child]; par[child] = parent; } }; #include <iostream> #include <vector> #include <queue> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; typedef pair<pll,ll> plll; ll p[200010],a[200010]; ll val[200010],cnt[200010],ans[200010]; struct Cmp{ bool operator()(const plll &l,const plll &r){ // cout << l.first.first << "/" << l.first.second << "," << r.first.first << "/" << r.first.second << endl; return l.first.first * r.first.second < l.first.second * r.first.first; } }; int main(){ int i,n; cin >> n; string s; cin >> s; for(i=1;i<=n;i++) cin >> a[i]; int now = 0,mx = 0; for(char c:s){ if(c=='('){ mx++; p[mx] = now; now = mx; }else{ now = p[now]; } } UF uf(n + 1); for(i=1;i<=n;i++) uf.cp_par[i] = p[i]; for(i=1;i<=n;i++) val[i] = a[i],cnt[i] = 1; priority_queue<plll,vector<plll>,Cmp> que; for(i=1;i<=n;i++) que.push({{val[i],cnt[i]},uf.find(i)}); val[0] = 0; cnt[0] = 1; while(que.size()){ auto [x,id] = que.top(); que.pop(); auto [v,c] = x; if(uf.find(id)!=id || val[id]!=v || cnt[id]!=c) continue; int pa = uf.find(uf.cp_par[id]); // cout << "id == " << id << " pa == " << pa << " " << v << " " << c << "\n"; // cout << "q_s " << que.size() << "\n"; ll nv = val[pa] + v,nc = cnt[pa] + c; ll nans = ans[pa] + ans[id] + cnt[pa]*v; uf.unite(id,pa); int n_id = uf.find(id); val[n_id] = nv; cnt[n_id] = nc; ans[n_id] = nans; if(!uf.same(0,n_id)) que.push({{val[n_id],cnt[n_id]},n_id}); // for(i=0;i<=n;i++) cout << "{" << val[i] << "," << cnt[i] << "," << ans[i] << "} "; // cout << "\n"; } cout << ans[uf.find(0)] << "\n"; // priority_queue<plll,vector<plll>,Cmp> que; // que.push({{1,2},2}); // que.push({{1,1},1}); // while(que.size()){ // auto [_,id] = que.top(); // que.pop(); // cout << "id == " << id << "\n"; // } }