cf600E. Lomsat gelral
題解: dsu on tree 實質上啟發式合併 我們考慮維護節點u的資訊 需要將u的兒子的資訊和節點資訊合併 我們考慮啟發式合併 把輕兒子合併到重兒子上 我們考慮n次啟發式合併 複雜度nlogn*(合併一次的複雜度) 具體做法那我們考慮樹鏈剖分的時候 劃分輕重兒子 保留重兒子資訊 清空輕兒子資訊 並將輕兒子的資訊合併到重兒子上即可
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=3e5+10; const double eps=1e-8; #define ll long long using namespace std; struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e; void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;} ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } int a[MAXN]; ll ans[MAXN];int cnt[MAXN],cc[MAXN]; int num[MAXN],son[MAXN]; void dfs(int x,int fa){ num[x]=1; link(x){ if(j->t!=fa){ dfs(j->t,x); num[x]+=num[j->t]; if(son[x]==-1||num[son[x]]<num[j->t])son[x]=j->t; } } } void Add(int pos,int key){ cnt[key]++; if(cnt[key]==cc[pos])ans[pos]+=key; else if(cnt[key]>cc[pos])ans[pos]=key,cc[pos]=cnt[key]; } void add(int x,int fa,int pos){ Add(pos,a[x]); link(x){ if(j->t!=fa)add(j->t,x,pos); } } void clear(int x,int fa){ cnt[a[x]]--; link(x){ if(j->t!=fa)clear(j->t,x); } } void dfs1(int x,int fa){ link(x){ if(j->t==fa||j->t==son[x])continue; dfs1(j->t,x); clear(j->t,x); } if(son[x]!=-1)dfs1(son[x],x),cc[x]=cc[son[x]],ans[x]=ans[son[x]]; link(x){ if(j->t==fa||j->t==son[x])continue; add(j->t,x,x); } Add(x,a[x]); } int main(){ int n=read(); inc(i,1,n)a[i]=read(),son[i]=-1; int u,v; inc(i,1,n-1)u=read(),v=read(),add(u,v),add(v,u); dfs(1,0);dfs1(1,0); inc(i,1,n)printf("%lld ",ans[i]); printf("\n"); }
You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour.
Let's call colour c dominating in the subtree of vertex v if there are no other colours that appear in the subtree of vertex v more times than colour c. So it's possible that two or more colours will be dominating in the subtree of some vertex.
The subtree of vertex v
For each vertex v find the sum of all dominating colours in the subtree of vertex v.
InputThe first line contains integer n (1 ≤ n ≤ 105) — the number of vertices in the tree.
The second line contains n integers ci (1 ≤ ci ≤ n), ci — the colour of the i-th vertex.
Each of the next n - 1 lines contains two integers xj, yj (1 ≤ xj, yj ≤ n) — the edge of the tree. The first vertex is the root of the tree.
OutputPrint n integers — the sums of dominating colours for each vertex.
Examples input Copy4output Copy
1 2 3 4
1 2
2 3
2 4
10 9 3 4input Copy
15output Copy
1 2 3 1 2 3 3 1 1 3 2 2 1 2 3
1 2
1 3
1 4
1 14
1 15
2 5
2 6
2 7
3 8
3 9
3 10
4 11
4 12
4 13
6 5 4 3 2 3 3 1 1 3 2 2 1 2 3