# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1089685 | Lib | Fireworks (APIO16_fireworks) | C++14 | 0 ms | 0 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
priority_queue <long long> pq[300003];
long long par[300003];
long long children[300003];
long long len[300003];
long long dp[300003];
int main(){
int n,m;
cin>>n>>m;
for(int i=2;i<=n;i++){
cin>>par[i]>>len[i];
children[i]++;
//this is a leaf
if(i>n){
dp[par[i]]-=len[i];
//Similar to other slope trick things. One push for the action of "shrinking the edge to 0", one push for the action of undoing the other one
pq[par[i]].push(len[i]);
pq[par[i]].push(len[i]);
}
}
//Merging answers from children to parent, pushing sub-pqs into top-pqs
for(int i=n;i>=2;i--){
for(int k=1;k<=children[i];k++){
//undo-ing the undo operations
dp[i]+=pq[i].top();
pq[i].pop();
long long opt1,opt2;
//2 most optimal undo operations
opt1=pq[i].top();
pq[i].pop();
opt2=pq[i].top();
pq[i].pop();
pq.push(opt1+len[i]);
pq.push(opt2+len[i]);
dp[i]-=len[i];//pre-paid
long long tmp;
dp[par[i]]+=dp[i];//pushing the answer to root
//classic small-to-large merging here
if(pq[par[i]].size()<pq[i].size()){
swap(pq[par[i]],pq[i]);
}
while(!pq[i].empty()){
tmp=pq[i].top();
pq[i].pop();
pq[par[i]].push(tmp);
}
}
}
long long ans=dp[1];
//final undo ops
for(int i=1;i<=children[1];i++){
dp[1]+=pq[1].top();
pq[1].pop();
}
cout<<ans;
}