线段树合并WA#6求调
  • 板块CF600E Lomsat gelral
  • 楼主P7GAB
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/11/19 16:44
  • 上次更新2024/11/19 18:57:09
查看原帖
线段树合并WA#6求调
508530
P7GAB楼主2024/11/19 16:44
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
int maxr=1e5+10,n;
struct tree {
	int l,r;
	int c,sum;
} t[maxn*50];
struct node {
	int nxt,to;
} edge[maxn<<1];
int ans[maxn];
int head[maxn],cnt=0,tot=0;
int root[maxn];
void add(int u,int v) {
	cnt++;
	edge[cnt].to=v;
	edge[cnt].nxt=head[u];
	head[u]=cnt;
}
int c[maxn];
void pushup(int p) {
	if(t[t[p].l].sum>t[t[p].r].sum)
		t[p].sum=t[t[p].l].sum,t[p].c=t[t[p].l].c;
	if(t[t[p].l].sum==t[t[p].r].sum)
		t[p].sum=t[t[p].l].sum,t[p].c=t[t[p].l].c+t[t[p].r].c;
	if(t[t[p].l].sum<t[t[p].r].sum)
		t[p].sum=t[t[p].r].sum,t[p].c=t[t[p].r].c;
}
void update(int &p,int x,int k,int l=1,int r=maxr) {
	if(!p) p=++tot;
	if(l==r) {
		t[p].sum+=k;
		t[p].c=l;
		return ;
	}
	int mid=(l+r)/2;
	if(x<=mid) update(t[p].l,x,k,l,mid);
	else update(t[p].r,x,k,mid+1,r);
	pushup(p);
}
int merge(int u,int v,int l,int r) {
	if(!u or !v) return u+v;
	if(l==r) {
		t[u].sum+=t[v].sum;
		t[u].c=l;
		return u;
	}
	int mid=(l+r)/2;
	t[u].l=merge(t[u].l,t[v].l,l,mid);
	t[u].r=merge(t[u].r,t[v].r,mid+1,r);
	pushup(u);
	return u;
}
void dfs(int u,int fa) {
	for(int i=head[u]; i; i=edge[i].nxt) {
		int v=edge[i].to;
		if(v==fa) continue;
		dfs(v,u);
		root[u]=merge(root[u],root[v],1,maxr);
	}
	update(root[u],c[u],1);
	ans[u]=t[root[u]].c;
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1; i<=n; i++)
		cin>>c[i];
	for(int i=1,u,v; i<n; i++) {
		cin>>u>>v;
		add(u,v),add(v,u);
	}
	dfs(1,0);
	for(int i=1; i<=n; i++) {
		cout<<ans[i]<<" ";
	}
	return 0;
}
2024/11/19 16:44
加载中...