Submission #47517

#TimeUsernameProblemLanguageResultExecution timeMemory
47517qoo2p5Construction of Highway (JOI18_construction)C++17
100 / 100
372 ms22216 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int INF = (int) 1e9 + 1e6 + 123; const ll LINF = (ll) 1e18 + 1e9 + 123; #define rep(i, s, t) for (auto i = (s); i < (t); ++(i)) #define per(i, s, t) for (auto i = (s); i >= (t); --(i)) #define sz(x) ((int)(x).size()) #define all(x) (x).begin(), (x).end() #define mp make_pair #define pb push_back bool mini(auto &x, const auto &y) { if (y < x) { x = y; return 1; } return 0; } bool maxi(auto &x, const auto &y) { if (y > x) { x = y; return 1; } return 0; } void run(); int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); run(); return 0; } const int N = (int) 1e5 + 123; struct F { int f[N]; void add(int x, int y) { x++; for (; x < N; x += x & (-x)) f[x] += y; } int get(int i) { i++; int res = 0; for (; i > 0; i -= i & (-i)) res += f[i]; return res; } }; int n; int c[N]; map<int, int> comp; vector<int> g[N]; struct HLD { int up, down; vector<pair<int, int>> st; void set(int len, int c) { int alr = 0; while (sz(st) && st.back().second + alr <= len) { alr += st.back().second; st.pop_back(); } assert(alr <= len); if (alr < len) { st.back().second -= (len - alr); } st.pb({c, len}); } }; int ptr; HLD hld[N]; int id[N]; int depth[N]; int cnt[N]; int p[N]; pair<int, int> q[N]; void precalc(int v) { cnt[v] = 1; for (int u : g[v]) { precalc(u); cnt[v] += cnt[u]; } } void build_hld(int v, int cur = -1) { if (cur == -1) { cur = ptr++; hld[cur].up = v; } id[v] = cur; hld[cur].down = v; int to = -1; for (int u : g[v]) { if (to == -1 || cnt[u] > cnt[to]) { to = u; } } if (to != -1) { build_hld(to, cur); } for (int u : g[v]) { if (u != to) { build_hld(u, -1); } } } F f; ll get(int v) { static vector<pair<int, int>> cool; cool.clear(); while (v > 0) { int w = id[v]; int len = depth[v] - depth[hld[w].up] + 1; int alr = 0; int ptr = sz(hld[w].st) - 1; while (ptr >= 0 && hld[w].st[ptr].second + alr <= len) { alr += hld[w].st[ptr].second; ptr--; } if (alr < len) { assert(ptr >= 0); cool.pb({hld[w].st[ptr].first, len - alr}); } rep(i, ptr + 1, sz(hld[w].st)) { cool.pb(hld[w].st[i]); } v = p[hld[w].up]; } ll ans = 0; for (auto &it : cool) { ans += it.second * f.get(it.first - 1); f.add(it.first, it.second); } for (auto &it : cool) { f.add(it.first, -it.second); } return ans; } void set_color(int v, int c) { while (v > 0) { int w = id[v]; int len = depth[v] - depth[hld[w].up] + 1; hld[w].set(len, c); v = p[hld[w].up]; } } void run() { cin >> n; rep(i, 1, n + 1) { cin >> c[i]; comp[c[i]] = 1; } { int ptr = 0; for (auto &it : comp) { it.second = ptr++; } } rep(i, 1, n + 1) { c[i] = comp[c[i]]; } rep(i, 1, n) { int a, b; cin >> a >> b; g[a].pb(b); p[b] = a; depth[b] = depth[a] + 1; q[i] = {a, b}; } precalc(1); build_hld(1); rep(i, 0, ptr) { hld[i].st.pb({-1, depth[hld[i].down] - depth[hld[i].up] + 1}); } set_color(1, c[1]); rep(i, 1, n) { cout << get(q[i].first) << "\n"; set_color(q[i].second, c[q[i].second]); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...