Submission #1228302

#TimeUsernameProblemLanguageResultExecution timeMemory
1228302MarwenElarbiConstruction of Highway (JOI18_construction)C++20
100 / 100
873 ms43336 KiB
#include <bits/stdc++.h> using namespace std; #define fi first #define se second const int nax=2e5+7; vector<int> adj[nax]; vector<pair<int,int>> edges; vector<int> colors(nax); vector<int> tab[nax]; vector<pair<int,int>> comp[nax]; int sz[nax],tp[nax],parent[nax],depth[nax]; int precompute_sz(int x,int p){ sz[x]=1; for(auto u:adj[x]){ if(u==p) continue; parent[u]=x; depth[u]=depth[x]+1; sz[x]+=precompute_sz(u,x); } return sz[x]; } void dfs_hld(int x,int p,int top){ tp[x]=top; pair<int,int> big_child={-1,-1}; for(auto u:adj[x]){ if(u==p) continue; big_child=max(big_child,make_pair(sz[u],u)); } if(big_child.fi != -1 )dfs_hld(big_child.se,x,top); for(auto u : adj[x]){ if(u==p||u==big_child.se) continue; dfs_hld(u,x,u); } return; } void dfs(int x,int p){ for(auto u:adj[x]){ if(u==p) continue; dfs(u,x); } tab[tp[x]].push_back(colors[x]); } vector<pair<int,int>> q; void query(int x,int c){ //cout <<x<<" "<<tp[x]<<endl; int cur=depth[x]-depth[tp[x]]+1; int cnt=0; vector<pair<int,int>> nab; while(cnt<cur){ cnt+=comp[tp[x]].back().se; nab.push_back(comp[tp[x]].back()); comp[tp[x]].pop_back(); } if(cnt>cur){ comp[tp[x]].push_back(nab.back()); comp[tp[x]].back().se=cnt-cur; nab.back().se-=comp[tp[x]].back().se; } comp[tp[x]].push_back({c,cur}); reverse(nab.begin(),nab.end()); for(auto u:nab) q.push_back(u); if(tp[x] != 0) query(parent[tp[x]],c); } int segtree[nax*4]; bool lazy[nax*4]; void extend(int pos){ if(lazy[pos]==0) return; segtree[pos*2+1]=0; lazy[pos*2+1]=1; segtree[pos*2+2]=0; lazy[pos*2+2]=1; lazy[pos]=0; } void update(int pos,int l,int r,int idx,int value){ if(l>r) return; extend(pos); if(l==r){ segtree[pos]+=value; return; } int mid=(r+l)/2; if(idx<=mid) update(pos*2+1,l,mid,idx,value); else update(pos*2+2,mid+1,r,idx,value); segtree[pos]=segtree[pos*2+1]+segtree[pos*2+2]; return; } int query(int pos,int l,int r,int left,int right){ if(l>r||l>right||r<left||right<left) return 0; extend(pos); if(left<=l&&r<=right) return segtree[pos]; int mid=(r+l)/2; return query(pos*2+1,l,mid,left,right)+query(pos*2+2,mid+1,r,left,right); } int main() { int n; cin>>n; map<int,vector<int>> mp; for (int i = 0; i < n; ++i) { cin>>colors[i]; mp[colors[i]].push_back(i); } int j=0; for(auto u:mp){ for(auto i:u.se) colors[i]=j; j++; } for (int i = 0; i < n-1; ++i) { int x,y; cin>>x>>y; x--;y--; edges.push_back({x,y}); adj[x].push_back(y); adj[y].push_back(x); } precompute_sz(0,-1); dfs_hld(0,-1,0); dfs(0,-1); for (int i = 0; i < n; ++i) { int lst=0; for (int j = 1; j < tab[i].size(); ++j) { if(tab[i][j]!=tab[i][j-1]){ comp[i].push_back({tab[i][j-1],j-lst}); lst=j; } } if(!tab[i].empty()) comp[i].push_back({tab[i].back(),tab[i].size()-lst}); } for (int i = 0; i < n-1; ++i) { q.clear(); lazy[0]=1; long long ans=0; query(edges[i].se,colors[edges[i].se]); for(int i=0;i<q.size();i++){ pair<int,int> u=q[i]; if(i==0&&u.se==1) continue; else if(i==0) u.se-=1; ans+=1ll*query(0,0,n-1,0,u.fi-1)*u.se; update(0,0,n-1,u.fi,u.se); } cout <<ans<<endl; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...