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;
#define int long long
int h[200005];
int c[200005];
vector<int> adjl[200005];
int in_cycle[200005];
///pos, increase
set<pair<int,int> > func(int node, bool fin = true){
set<pair<int,int> > res1;
for (auto x : adjl[node]){
if (in_cycle[x]) continue;
auto res = func(x);
if (res.size()>res1.size()) swap(res,res1);
for (auto y : res){
auto it = res1.lower_bound({y.first,-1});
if (it!=res1.end() && (*it).first==y.first){
int t = (*it).second;
res1.erase(it);
res1.insert({y.first,y.second+t});
}
else{
res1.insert({y.first,y.second});
}
}
}
if (!fin) return res1;
pair<int,int> to_insert = {h[node]+1,c[node]};
int cursum = 0;
auto it = res1.lower_bound({h[node]+1,-1});
if (it!=res1.end() && (*it).first==to_insert.first){
int t = (*it).second;
res1.erase(it);
res1.insert({to_insert.first,to_insert.second+t});
}
else{
res1.insert(to_insert);
}
it = res1.lower_bound(to_insert);
bool done = false;
while (it!=res1.begin()){
it--;
cursum += (*it).second;
int curpos = (*it).first;
it = res1.erase(it);
if (cursum >= c[node]){
int rem = cursum-c[node];
if (rem!=0){
res1.insert({curpos,rem});
}
done = true;
break;
}
}
if (!done){
if (cursum!=0){
if ((!res1.empty()) && (*res1.begin()).first==0){
cursum += (*res1.begin()).second;
res1.erase(res1.begin());
res1.insert({0,cursum});
}
else
res1.insert({0,cursum});
}
}
else{
if ((!res1.empty()) && (*res1.begin()).first==0){
int t = (*res1.begin()).second;
res1.erase(res1.begin());
res1.insert({0,c[node]+t});
}
else
res1.insert({0,c[node]});
}
/*printf("node %lld, ret ",node);
for (auto x : res1){
printf("(%lld,%lld) ",x);
}
printf("\n");*/
return res1;
}
int p[200005];
int vis[200005];
main(){
int n;
scanf("%lld",&n);
for (int x = 1; x<=n; x++){
int t;
scanf("%lld%lld%lld",&t,&h[x],&c[x]);
p[x] = t;
adjl[t].push_back(x);
}
vector<pair<int,vector<int> > > roots;
for (int x = 1; x<=n; x++){
if (vis[x]) continue;
int c1 = x, c2 = x;
c1 = p[c1]; c2 = p[p[c2]];
bool found = false;
while (c1!=c2){
if (vis[c1]) {
found = true;
break;
}
vis[c1] = true;
c1 = p[c1]; c2 = p[p[c2]];
}
if (found||vis[c1]) continue;
vis[c1] = true;
in_cycle[c1] = true;
vector<int> curcycle;
c2 = p[c2];
while (c2!=c1){
curcycle.push_back(c2);
vis[c2] = true;
in_cycle[c2] = true;
c2 = p[c2];
}
for (auto x : curcycle){
for (auto y : adjl[x]){
if (!in_cycle[y]){
adjl[c1].push_back(y);
}
}
}
curcycle.push_back(c1);
/* printf("cycle found: ");
for (auto x : curcycle) printf("%lld ",x);
printf("\n");*/
roots.push_back({c1,curcycle});
}
int ans = 0;
for (auto x : roots){
int root = x.first;
int curans = 0;
vector<pair<int,int> >stuff;
for (auto y : x.second){
stuff.push_back({h[y],c[y]});
curans += c[y];
}
auto res = func(root,false);
int cur = 0;
stuff.push_back({0,0});
sort(stuff.begin(),stuff.end());
vector<pair<int,int> > newstuff;
for (int x = 0; x<stuff.size(); x++){
if (x!=0 && stuff[x].first==newstuff.back().first){
newstuff.back().second+=stuff[x].second;
}
else newstuff.push_back(stuff[x]);
}
swap(newstuff,stuff);
auto it = res.begin();
int best = 999999999999999999LL;
for (auto val : stuff){
while (it!=res.end() && (*it).first<=val.first){
cur += (*it).second;
it++;
}
best = min(best,cur+curans-val.second);
// printf("try values %lld, %lld %lld\n",cur,val);
}
ans += best;
}
printf("%lld",ans);
}
Compilation message (stderr)
worst_reporter2.cpp:88:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
88 | main(){
| ^~~~
worst_reporter2.cpp: In function 'int main()':
worst_reporter2.cpp:149:26: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
149 | for (int x = 0; x<stuff.size(); x++){
| ~^~~~~~~~~~~~~
worst_reporter2.cpp:90:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
90 | scanf("%lld",&n);
| ~~~~~^~~~~~~~~~~
worst_reporter2.cpp:93:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
93 | scanf("%lld%lld%lld",&t,&h[x],&c[x]);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |