Submission #799962

#TimeUsernameProblemLanguageResultExecution timeMemory
799962phoenixConstruction of Highway (JOI18_construction)C++17
100 / 100
185 ms20656 KiB
#include<bits/stdc++.h> using namespace std; using ll = long long; const int N = 1e5 + 10; struct object { int color, len; }; ll numberOfInverse(object *a, int n) { static object b[N]; if(n == 1) return 0; ll ans = numberOfInverse(a, n / 2) + numberOfInverse(a + n / 2, (n + 1) / 2); int lb = 0, rb = 0, sum = 0; for(int i = n / 2; i < n; i++) { while(lb < n / 2 && a[lb].color < a[i].color) sum += a[lb++].len; ans += 1ll * a[i].len * sum; } lb = 0, rb = n / 2; for(int i = 0; i < n; i++) { if(lb == n / 2) { b[i] = a[rb++]; continue; } if(rb == n) { b[i] = a[lb++]; continue; } b[i] = (a[lb].color <= a[rb].color ? a[lb++] : a[rb++]); } for(int i = 0; i < n; i++) a[i] = b[i]; return ans; } int n; int C[N]; int sz[N]; int head[N]; int depth[N]; int heavy[N]; int parent[N]; vector<object> v[N]; vector<pair<int, int>> edges; vector<int> g[N]; void precalc(int s, int p) { parent[s] = p; sz[s] = 1; for(int to : g[s]) { depth[to] = depth[s] + 1; precalc(to, s); sz[s] += sz[to]; if(sz[heavy[s]] < sz[to]) heavy[s] = to; } } void decompose(int s, int h) { head[s] = h; if(heavy[s]) decompose(heavy[s], h); for(int to : g[s]) { if(to == heavy[s]) continue; decompose(to, to); } v[h].push_back({C[s], 1}); } int len = 0; object t[N]; ll query(int a, int x) { for(int ver = a; ver; ver = parent[head[ver]]) { int u = head[ver]; int k = depth[ver] - depth[u] + 1; vector<object> t1; while(v[u].back().len <= k) { k -= v[u].back().len; t1.push_back(v[u].back()); v[u].pop_back(); } if(k) { object z = {v[u].back().color, k}; v[u].back().len -= k; t1.push_back(z); k = 0; } v[u].push_back({x, depth[ver] - depth[u] + 1}); while(!t1.empty()) { t[len++] = t1.back(); t1.pop_back(); } } // for(int i = 0; i < len; i++) // cerr << '(' << t[i].color << ' ' << t[i].len << ')' << ' '; // cout << '\n'; ll res = numberOfInverse(t, len); len = 0; return res; } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); cin >> n; for(int i = 1; i <= n; i++) cin >> C[i]; for(int i = 1; i < n; i++) { int a, b; cin >> a >> b; edges.push_back({a, b}); g[a].push_back(b); } precalc(1, 0); decompose(1, 1); for(auto [a, b] : edges) { cout << query(a, C[b]) << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...