Submission #234956

#TimeUsernameProblemLanguageResultExecution timeMemory
234956oolimryConstruction of Highway (JOI18_construction)C++14
16 / 100
582 ms23368 KiB
#include <bits/stdc++.h> #define all(x) x.begin(), x.end() using namespace std; typedef pair<long long, long long> ii; int n; int cnt = 0; int arr[100005]; int low[100005]; int high[100005]; int p[100005][20]; vector<int> adj[100005]; vector<ii> edges; ///segment tree ii tree[200005]; int timer = 1; void update(int i, int v){ for(i += n;i > 0;i >>= 1) tree[i] = ii(timer, v); timer++; } ii query(int u){ int l = low[u], r = high[u]; ii res = ii(0,0); for(l += n, r += n+1;l < r;l >>= 1, r >>= 1){ if(l&1) res = max(res, tree[l++]); if(r&1) res = max(res, tree[--r]); } return res; } ///segment tree ///segment tree 2 int tree2[100005]; void update2(int i, int v){ for(i += n;i > 0;i >>= 1) tree2[i] += v; } long long query2(int l, int r){ long long res = 0; for(l += n, r += n;l < r;l >>= 1, r >>= 1){ if(l&1) res += tree2[l++]; if(r&1) res += tree2[--r]; } return res; } ///segment tree 2 void dfs(int u, int P){ low[u] = cnt; cnt++; high[u] = low[u]; for(int v : adj[u]){ if(v == P) continue; dfs(v, u); p[v][0] = u; high[u] = max(high[u], high[v]); } update(low[u], arr[u]); } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); cin >> n; vector<int> discrodile; for(int i = 1;i <= n;i++){ cin >> arr[i]; discrodile.push_back(arr[i]); } sort(discrodile.begin(), discrodile.end()); discrodile.erase(unique(all(discrodile)), discrodile.end()); for(int i = 1;i <= n;i++){ arr[i] = lower_bound(all(discrodile), arr[i]) - discrodile.begin(); } for(int i = 1;i < n;i++){ int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); edges.push_back(ii(u,v)); } dfs(1,0); for(int d = 1;d <= 19;d++){ for(int i = 1;i <= n;i++){ p[i][d] = p[p[i][d-1]][d-1]; //cout << p[i][d] << " "; } //cout << "\n"; } for(ii e : edges){ int u = e.first, v = e.second; ///extend tree from u to v; //cout << "\n" << u << " " << v << ":\n"; vector<ii> parts; while(true){ ii root = query(u); int sz = 1; for(int d = 19;d >= 0;d--){ int nu = p[u][d]; if(nu == 0) continue; if(query(nu) != root) continue; u = nu; sz += (1 << d); } //cout << root.first << " " << root.second << " " << sz << "\n"; parts.push_back(ii(root.second, sz)); if(u == 1) break; u = p[u][0]; } long long ans = 0; for(ii x : parts){ ans += x.second * query2(0, x.first); update2(x.first, x.second); } for(ii x : parts) update2(x.first, -x.second); ///undo cout << ans << "\n"; update(low[v], arr[v]); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...