题意:。。比较复杂,就是一个树有点权,一个点的答案是子树的所有点权的前缀和的和(贪心思想转换后的题意),问所有答案。
首先这是个假题解。。只是提供一个思路。。。数据不强AC了。。。
思路:标解是个启发式合并。。这里尝试另一种做法(因为不会),平均时间复杂度是nlogn^2。(数据弱。。)考虑合并操作复杂,我们可以分为合并暴力,单个儿子直接得答案两种操作解决问题。(看起来很玄学。。),事实上是这样的,单个儿子的时间复杂度不用解释,肯定是正确的,我们只要维护子树离散化后的个数以及一个sum。对于暴力这部分。。其实也是一拍脑子想出来的。。首先有一个二叉结点我们就要暴力他的子树一次,当他是一个满二叉树的时候,整个排序的过程就类似一个归并树(事实上多一个sort的log),那么其实这个暴力就类似快排了,随机数据下时间复杂度是科学的。。
代码:
#include<bits/stdc++.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof(a))
#define bug puts("bug");
#define PB push_back
#define MP make_pair
#define X first
#define Y second
typedef unsigned long long ll;
typedef pair<int,int> pii;
const int maxn=1e5+100;
const int mod=1e9+7;
using namespace std;
ll sum;
int id[maxn],L[maxn],R[maxn],x,y,n,t,tim,cnt[maxn];
ll b[maxn],a[maxn],hs[maxn],bit[maxn],ans[maxn],sbit[maxn];
vector<int> v[maxn];
void add(int x,int y){
v[x].PB(y),v[y].PB(x);
}
int dfs(int x,int f){
int ret=1;
L[x]=tim++;
b[L[x]]=a[x];
for(int i=0;i<v[x].size();i++)
if(v[x][i]!=f)ret+=dfs(v[x][i],x);
R[x]=tim-1;
return cnt[x]=ret;
}
int lowbit(int x){
return x&(-x);
}
void modify(int x,ll add,ll a[]){
while(x<maxn){
a[x]+=add;
x+=lowbit(x);
}
}
ll get_sum(ll x,ll a[]){
ll ret=0;
while(x!=0){
ret+=a[x];
x-=lowbit(x);
}
return ret;
}
void del(int x,int f){
modify(id[x],-1,bit);
modify(id[x],-a[x],sbit);
for(int i=0;i<v[x].size();i++)
if(v[x][i]!=f)del(v[x][i],x);
}
void addx(int x,int f){
modify(id[x],1,bit);
modify(id[x],a[x],sbit);
for(int i=0;i<v[x].size();i++)
if(v[x][i]!=f)addx(v[x][i],x);
}
void sl(int x,int f){
vector<int> son;
for(int i=0;i<v[x].size();i++)
if(v[x][i]!=f)son.PB(v[x][i]);
int siz=son.size();
if(siz==0)ans[x]=a[x];
else if(siz==1){
sl(son[0],x);
ans[x]=ans[son[0]]+(get_sum(n+10,bit)-get_sum(id[x],bit))*a[x]+get_sum(id[x],sbit)+a[x];
}
else if(siz==2){
int aa=0,bb=1;
if(cnt[son[0]]>cnt[son[1]]) swap(aa,bb);
sl(son[aa],x);
del(son[aa],x);
sl(son[bb],x);
addx(son[aa],x);
sort(b+L[x],b+R[x]+1);
sum=0;
for(int i=L[x];i<=R[x];i++)sum+=b[i],ans[x]+=sum;
}
modify(id[x],1,bit);
modify(id[x],a[x],sbit);
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
tim=1;
MEM(sbit,0),MEM(bit,0);MEM(ans,0);MEM(cnt,0);
for(int i=0;i<=n+2;i++) v[i].clear();
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++) hs[i]=a[i];
sort(hs+1,hs+n+1);
int N=unique(hs+1,hs+n+1)-hs;
for(int i=1;i<=n;i++) id[i]=lower_bound(hs+1,hs+N,a[i])-hs+1;
for(int i=0;i<n-1;i++) scanf("%d%d",&x,&y),add(x,y);
dfs(1,-1);
sl(1,-1);
for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
puts("");
}
}