結果
| 問題 |
No.3148 Min-Cost Destruction of Parentheses
|
| コンテスト | |
| ユーザー |
pockyny
|
| 提出日時 | 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";
// }
}
pockyny