Submission #1194229

#TimeUsernameProblemLanguageResultExecution timeMemory
1194229byunjaewooConstruction of Highway (JOI18_construction)C++20
100 / 100
814 ms38096 KiB
#include <bits/stdc++.h> #define int long long using namespace std; const int N=100010, L=18, S=(1<<17); int n, a[N], b[N], c[N]; int par[L][N], siz[N], dep[N], t, in[N], top[N], gp[N]; vector<int> com; vector<int> adj[N]; class LazyProp { public: void update(int l, int r, int v) {update(1, 1, S, l, r, v);} int query(int k) {return query(1, 1, S, k);} private: int tree[2*S], lazy[2*S]; void propagate(int node, int s, int e) { if (!lazy[node]) return; if (s!=e) lazy[2*node]=lazy[2*node+1]=lazy[node]; else tree[node]=lazy[node]; lazy[node]=0; } void update(int node, int s, int e, int l, int r, int v) { propagate(node, s, e); if (s>r || l>e) return; if (l<=s && e<=r) { lazy[node]=v, propagate(node, s, e); return; } int lch=2*node, rch=lch+1, m=(s+e)/2; update(lch, s, m, l, r, v), update(rch, m+1, e, l, r, v); } int query(int node, int s, int e, int k) { propagate(node, s, e); if (s==e) return tree[node]; int lch=2*node, rch=lch+1, m=(s+e)/2; if (k<=m) return query(lch, s, m, k); return query(rch, m+1, e, k); } }T; class Fenwick { public: void update(int k, int v) { for (int i=k; i<=n; i+=i&-i) tree[i]+=v; } int query(int k) { int ret=0; for (int i=k; i>=1; i-=i&-i) ret+=tree[i]; return ret; } private: int tree[N]; }T2; void dfs(int curr) { for (int i=1; i<L; i++) par[i][curr]=par[i-1][par[i-1][curr]]; siz[curr]=1; for (int next:adj[curr]) { par[0][next]=curr, dep[next]=dep[curr]+1, dfs(next), siz[curr]+=siz[next]; } for (int &next:adj[curr]) if (siz[next]>siz[adj[curr][0]]) swap(next, adj[curr][0]); } void dfs2(int curr) { in[curr]=++t; for (int next:adj[curr]) { if (next==adj[curr][0]) top[next]=top[curr]; else top[next]=next; dfs2(next); } } int lift(int x, int y) { for (int i=L-1; i>=0; i--) if (par[i][x] && dep[par[i][x]]>dep[y]) x=par[i][x]; return x; } int query(int x) { vector<array<int, 2>> vec; while (x) { int tmp=T.query(in[x]); vec.push_back({c[tmp], dep[x]-dep[gp[tmp]]+1}); int ttmp=par[0][gp[tmp]]; gp[tmp]=lift(tmp, x); x=ttmp; } int ret=0; for (int i=0; i<vec.size(); i++) { ret+=T2.query(vec[i][0]-1)*vec[i][1], T2.update(vec[i][0], vec[i][1]); } for (int i=0; i<vec.size(); i++) T2.update(vec[i][0], -vec[i][1]); return ret; } void update(int x, int v) { gp[v]=1; while (x) T.update(in[top[x]], in[x], v), x=par[0][top[x]]; } signed main() { ios_base::sync_with_stdio(0), cin.tie(0); cin>>n; for (int i=1; i<=n; i++) cin>>c[i], com.push_back(c[i]); sort(com.begin(), com.end()), com.erase(unique(com.begin(), com.end()), com.end()); for (int i=1; i<=n; i++) c[i]=lower_bound(com.begin(), com.end(), c[i])-com.begin()+1; for (int i=1; i<n; i++) { cin>>a[i]>>b[i]; adj[a[i]].push_back(b[i]); } dfs(1), dfs2(1); for (int i=1; i<=n; i++) T.update(in[i], in[i], i), gp[i]=i; for (int i=1; i<n; i++) { cout<<query(a[i])<<"\n"; update(a[i], b[i]); } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...