线段树合并 WA on #3 求助
查看原帖
线段树合并 WA on #3 求助
572133
潘德理2010楼主2023/11/20 23:09
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,c[100010],a,b,vis[100010];
vector<int> e[100010];//邻接表 
int rt[100010],mx[100010],l[3200010],r[3200010],s[3200010],cnt;
ll ans[100010];
//rt根节点 ans颜色和 mx最大出现次数 l左孩子 r右孩子 s出现次数 
int add(int le,int ri,int x){
	int u=++cnt,mid=(le+ri)/2;
	s[u]=1;
	if(le==ri) return u;
	if(x<=mid) l[u]=add(le,mid,x);
	else r[u]=add(mid+1,ri,x);
	return u;
}
int meg(int x,int y,int le,int ri,int k){
	int mid=(le+ri)/2;
	if(!x) return y;
	if(!y) return x;
	s[x]+=s[y];
	if(le==ri){
		if(s[x]>mx[k]){
			ans[k]=c[le];
			mx[k]=s[x];
		}
		else if(s[x]==mx[k]){
			ans[k]+=c[le];
		}
		return x;
	}
	l[x]=meg(l[x],l[y],le,mid,k);
	r[x]=meg(r[x],r[y],mid+1,ri,k);	
	return x;
}
void dfs(int u){
	vis[u]=1;
	for(int i=0;i<int(e[u].size());i++){
		int v=e[u][i];
		if(!vis[v]){
			dfs(v);
			rt[u]=meg(rt[u],rt[v],1,n,u);
			if(mx[u]<mx[v]){
				mx[u]=mx[v];
				ans[u]=ans[v];
			}
			else if(mx[u]==mx[v]){
				ans[u]+=ans[v];
			}						
		}
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&c[i]);
		rt[i]=add(1,n,c[i]);
		mx[i]=1;
		ans[i]=c[i];
	}
	for(int i=1;i<n;i++){
		scanf("%d%d",&a,&b);
		e[a].push_back(b);
		e[b].push_back(a);
	}
	dfs(1);
	for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
}
2023/11/20 23:09
加载中...