Submission #1232583

#TimeUsernameProblemLanguageResultExecution timeMemory
1232583banganTree (IOI24_tree)C++20
41 / 100
2097 ms49004 KiB
#include "tree.h" #include <bits/stdc++.h> using namespace std; #define ll long long #define chmin(a, b) a = min(a, b) #define chmax(a, b) a = max(a, b) #define X first #define Y second #define pii pair<ll, ll> #define pb push_back const int N = 2e5 + 4; // const ll INF = 1ll << 60; ll n; vector<ll> p, w; vector<ll> adj[N]; ll sz[N], imp[N]; void prep(int v) { sz[v] = 1; imp[v] = -1; for (int u : adj[v]) { prep(u); sz[v] += sz[u]; if (imp[v] == -1 || sz[imp[v]] < sz[u]) imp[v] = u; } } void init(std::vector<int> P, std::vector<int> W) { n = P.size(); p.resize(n); for (int i=0; i<n; i++) p[i] = P[i]; w.resize(n); for (int i=0; i<n; i++) w[i] = W[i]; for (int i=1; i<n; i++) adj[p[i]].pb(i); prep(0); } ll last = 0; ll len = 0; multiset<pii> ret; void dfs(int v, ll l, ll r) { if (adj[v].empty()) { ret.insert({w[v], r-l}); last = r * w[v]; len = r-l; return; } multiset<pii> slope; ll cur_last = 0; ll cur_len = 0; last = len = 0; ret.clear(); dfs(imp[v], l, r); swap(slope, ret); cur_last += last; cur_len += len; for (int u : adj[v]) if (u != imp[v]) { last = len = 0; ret.clear(); dfs(u, l, r); for (auto t : ret) slope.insert(t); cur_last += last; cur_len += len; } last = cur_last; len = cur_len; { ll k = adj[v].size(); ll c = l*k - l; while (!slope.empty() && slope.begin()->X < -w[v]) { c += slope.begin()->Y; len -= slope.begin()->Y; slope.extract(*slope.begin()); } // if (slope.empty()) last += -w[v] * c; slope.insert({-w[v], c}); len += c; c = N; last += w[v]*c; slope.insert({w[v], c}); len += c; } ll del = len - (r-l); assert(0<=del); while (del != 0) { auto [x, c] = *slope.rbegin(); slope.extract(*slope.rbegin()); ll t = min(del, c); last -= t*x; len -= t; del -= t; c -= t; if (0<c) slope.insert({x, c}); } // cout << endl; // cout << "v = " << v << endl; // cout << "last = " << last << endl; // cout << "w[" << v << "] = " << w[v] << endl; // for (auto [x, c] : slope) { // while (c--) cout << x << ' '; // } // cout << endl; swap(ret, slope); } long long query(int L, int R) { last = len = 0; ret.clear(); dfs(0, L, R); ll ans = last; // cout << "last = " << last << endl; for (auto [x, c] : ret) { if (0<x) ans -= x*c; } return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...