Submission #20691

#TimeUsernameProblemLanguageResultExecution timeMemory
20691NamnamseoFireworks (APIO16_fireworks)C++14
100 / 100
1989 ms82944 KiB
#include <bits/stdc++.h> using namespace std; void read(int& x){ scanf("%d",&x); } typedef long long ll; void read(ll& x){ scanf("%lld",&x); } template<typename T,typename... Args> void read(T& a,Args&... b){ read(a); read(b...); } #define pb push_back #define all(x) (x).begin(),(x).end() typedef pair<int,ll> pp; int n; vector<pp> edge[300010]; void in(){ int m; read(n, m); n += m; for(int i=2; i<=n; ++i){ int a; ll b; read(a,b); edge[a].pb({i, b}); } } struct tree_result { map<ll,ll> dy_points; ll start_val, start_grad, end_grad; tree_result(){ start_grad = 0; end_grad = 0; start_val = 0; } void applyDistance(ll d){ if(dy_points.size() == 0u){ dy_points[d] = 2; start_val = d; start_grad = -1; end_grad = 1; return; } ll cur_grad = end_grad, bef_grad = -1, change_pt=-1, bef_pt=-1; for(auto it = --dy_points.end();;){ bef_grad = cur_grad; cur_grad -= it->second; bef_pt = change_pt; change_pt = it->first; if(cur_grad <= -1) break; it = --dy_points.erase(it); } dy_points.erase(--dy_points.end()); start_val += d; if(bef_grad == 0){ if(cur_grad != -1){ dy_points[change_pt] = -1 - cur_grad; } dy_points[change_pt + d] = 1; dy_points[bef_pt + d] = 1; } else { if(cur_grad != -1){ dy_points[change_pt] = -1 - cur_grad; } dy_points[change_pt + d] = 2; } end_grad = 1; } tree_result operator+(tree_result& r){ tree_result ret; ret.start_val = start_val + r.start_val; ret.start_grad = start_grad + r.start_grad; ret.end_grad = end_grad + r.end_grad; auto &a = dy_points, &b = r.dy_points; if(a.size() < b.size()) swap(a, b); swap(ret.dy_points, a); for(auto it=b.begin(); it!=b.end();){ ret.dy_points[it->first] += it->second; it = b.erase(it); } return ret; } }; int par[300010]; tree_result res[300010]; int sI[300010], top; pp last[300010]; void dfs(int x){ sI[top++]=x; while(top){ x=sI[top-1]; if(last[x].first){ int y, d; tie(y, d) = last[x]; res[y].applyDistance(d); if(res[x].dy_points.size() == 0u){ res[x] = res[y]; } else { res[x] = res[x] + res[y]; } res[y].dy_points.clear(); last[x] = {0, 0}; } if(edge[x].size() == 0u){ --top; continue; } else { int y, d; tie(y, d) = edge[x].back(); edge[x].pop_back(); if(y == par[x]) continue; par[y] = x; last[x] = {y, d}; sI[top++] = y; } } } int main() { in(); dfs(1); auto res = ::res[1]; ll val = res.start_val; ll grad = res.start_grad; ll min_val = 1LL << 62; ll last_pt = 0; for(auto tmp : res.dy_points){ ll cur_pt, cur_dg; tie(cur_pt, cur_dg) = tmp; val += grad * (cur_pt - last_pt); min_val = min(min_val, val); last_pt = cur_pt; grad += cur_dg; } printf("%lld\n", min_val); return 0; }

Compilation message (stderr)

fireworks.cpp: In function 'void read(int&)':
fireworks.cpp:3:34: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
 void read(int& x){ scanf("%d",&x); }
                                  ^
fireworks.cpp: In function 'void read(ll&)':
fireworks.cpp:5:35: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
 void read(ll& x){ scanf("%lld",&x); }
                                   ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...