#include <bits/stdc++.h>
using namespace std;
int const NMAX=100005;
int const LOG=20;
int n;
int v[NMAX];
vector<int>tree[NMAX];
struct edge{
int u,v;
}edges[NMAX];
void read(){
cin>>n;
int i;
for(i=1;i<=n;++i)
cin>>v[i];
for(i=1;i<n;++i){
int u,v;
cin>>u>>v;
edges[i]={u,v};
tree[u].push_back(v);
tree[v].push_back(u);
}
}
void normalize(){
map<int,int>mep;
int i;
for(i=1;i<=n;++i)
mep[v[i]]=0;
int ind=0;
for(auto &[orig_val,new_val] : mep)
new_val=++ind;
for(i=1;i<=n;++i)
v[i]=mep[v[i]];
}
int lift[NMAX][LOG];
int subsz[NMAX];
int h[NMAX];
void dfs(int nod){
int i;
for(i=1;i<LOG;++i)
lift[nod][i]=lift[lift[nod][i-1]][i-1];
subsz[nod]=1;
for(auto fiu : tree[nod])
if(fiu!=lift[nod][0]){
lift[fiu][0]=nod;
h[fiu]=h[nod]+1;
dfs(fiu);
subsz[nod]+=subsz[fiu];
}
}
int id[NMAX],leader[NMAX];
void hld(int nod){
static int time=0;
id[nod]=++time;
if(!leader[nod])
leader[nod]=nod;
int heavy_son=0;
for(auto fiu : tree[nod])
if(fiu!=lift[nod][0] && subsz[fiu]>subsz[heavy_son])
heavy_son=fiu;
if(heavy_son){
leader[heavy_son]=leader[nod];
hld(heavy_son);
for(auto fiu : tree[nod])
if(fiu!=lift[nod][0] && fiu!=heavy_son)
hld(fiu);
}
}
struct segment_tree{
int v[4*NMAX];
void update(int nod,int st,int dr,int a,int b,int val){
if(a<=st && dr<=b)
v[nod]=val;
else{
if(v[nod]){
v[2*nod]=v[nod];
v[2*nod+1]=v[nod];
v[nod]=0;
}
int mij=(st+dr)/2;
if(a<=mij)
update(2*nod,st,mij,a,b,val);
if(b>mij)
update(2*nod+1,mij+1,dr,a,b,val);
}
}
int query(int nod,int st,int dr,int pos){
if(v[nod])
return v[nod];
if(st==dr)
return -1;
int mij=(st+dr)/2;
if(pos<=mij)
return query(2*nod,st,mij,pos);
else
return query(2*nod+1,mij+1,dr,pos);
}
}aint;
struct fenwick_tree{
int v[NMAX];
int ub(int x){
return x&(-x);
}
void add(int pos,int val){
while(pos<=n){
v[pos]+=val;
pos+=ub(pos);
}
}
int qry(int pos){
int s=0;
while(pos){
s+=v[pos];
pos-=ub(pos);
}
return s;
}
}aib;
long long process_query(int nod){
long long ans=0;
vector<pair<int,int>>upds;
while(nod){
int i;
int anc=nod;
int tip=aint.query(1,1,n,id[nod]);
for(i=LOG-1;i>=0;--i)
if(lift[anc][i] && tip==aint.query(1,1,n,id[lift[anc][i]]))
anc=lift[anc][i];
ans+=1LL*(h[nod]-h[anc]+1)*aib.qry(v[tip]-1);
aib.add(v[tip],h[nod]-h[anc]+1);
upds.push_back({v[tip],h[nod]-h[anc]+1});
nod=lift[anc][0];
}
for(auto [pos,val] : upds)
aib.add(pos,-val);
return ans;
}
void process_update(int nod){
int orig_nod=nod;
while(nod){
aint.update(1,1,n,id[leader[nod]],id[nod],orig_nod);
nod=lift[leader[nod]][0];
}
}
void solve(){
aint.update(1,1,n,1,1,v[1]);
int i;
for(i=1;i<n;++i){
auto [u,v]=edges[i];
if(v==lift[u][0])
swap(u,v);
cout<<process_query(u)<<'\n';
process_update(v);
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
read();
normalize();
dfs(1);
hld(1);
solve();
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |