Lomsat gelral

Lomsat gelral

http://codeforces.com/contest/600/problem/E

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 is the vertex v and all other vertices that contains vertex v in each path to the root.

For each vertex v find the sum of all dominating colours in the subtree of vertex v.

Input

The 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.

Output

Print n integers — the sums of dominating colours for each vertex.

Examples
input
Copy
4
1 2 3 4
1 2
2 3
2 4
output
Copy
10 9 3 4
input
Copy
15
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
output
Copy
6 5 4 3 2 3 3 1 1 3 2 2 1 2 3



题意:求各个子树上颜色最多的值的和

思路:跑dfs的时候建主席树,然后按要求合并区间即可

  1 #include<bits/stdc++.h>
  2 typedef long long ll;
  3 #define ls tree[rt].l
  4 #define rs tree[rt].r
  5 #define pb push_back
  6 #define maxn 100005
  7 using namespace std;
  8 
  9 ll n;
 10 ll a[maxn];
 11 ll cnt;
 12 struct sair{
 13     ll l,r,sum,ans;
 14 }tree[maxn*40];
 15 ll root[maxn];
 16 vector<ll>ve[maxn];
 17 
 18 void push_up(ll rt){
 19    // cout<<tree[ls].sum<<" "<<tree[rs].sum<<"h"<<endl;
 20     if(tree[ls].sum>tree[rs].sum){
 21       //  cout<<1<<endl;
 22         tree[rt].sum=tree[ls].sum;
 23         tree[rt].ans=tree[ls].ans;
 24     }
 25     else if(tree[rs].sum>tree[ls].sum){
 26      //   cout<<2<<endl;
 27         tree[rt].sum=tree[rs].sum;
 28         tree[rt].ans=tree[rs].ans;
 29     }
 30     else{
 31       //  cout<<3<<endl;
 32         tree[rt].sum=tree[ls].sum;
 33         tree[rt].ans=tree[ls].ans+tree[rs].ans;
 34     }
 35 }
 36 
 37 void add(ll now,ll pos,ll l,ll r){
 38     if(l==r){
 39         tree[now].ans=l;
 40         tree[now].sum+=1;
 41         return;
 42     }
 43     ll mid=l+r>>1;
 44     if(pos<=mid){
 45         if(!tree[now].l){
 46             tree[now].l=++cnt;
 47         }
 48         add(tree[now].l,pos,l,mid);
 49     }
 50     else{
 51         if(!tree[now].r){
 52             tree[now].r=++cnt;
 53         }
 54         add(tree[now].r,pos,mid+1,r);
 55     }
 56     push_up(now);
 57 }
 58 
 59 void join(ll pre,ll now,ll l,ll r){
 60     if(l==r){
 61       //  cout<<tree[now].sum<<" "<<tree[pre].sum<<endl;
 62         tree[now].sum+=tree[pre].sum;
 63         tree[now].ans=l;
 64         return;
 65     }
 66     ll mid=l+r>>1;
 67     if(tree[pre].l&&tree[now].l){
 68         join(tree[pre].l,tree[now].l,l,mid);
 69     }
 70     if(tree[pre].r&&tree[now].r){
 71         join(tree[pre].r,tree[now].r,mid+1,r);
 72     }
 73     if(!tree[now].l){
 74         tree[now].l=tree[pre].l;
 75     }
 76     if(!tree[now].r){
 77         tree[now].r=tree[pre].r;
 78     }
 79 
 80     push_up(now);
 81 }
 82 
 83 void dfs(ll now,ll pre){
 84     for(ll i=0;i<ve[now].size();i++){
 85         if(ve[now][i]!=pre){
 86             dfs(ve[now][i],now);
 87             if(!root[now]){
 88                 root[now]=++cnt;
 89             }
 90             join(root[ve[now][i]],root[now],1,100000);
 91         }
 92     }
 93     if(!root[now]){
 94         root[now]=++cnt;
 95     }
 96     add(root[now],a[now],1,100000);
 97 }
 98 
 99 int main(){
100     std::ios::sync_with_stdio(false);
101     cin>>n;
102     for(ll i=1;i<=n;i++){
103         cin>>a[i];
104     }
105     ll u,v;
106     for(ll i=1;i<n;i++){
107         cin>>u>>v;
108         ve[u].pb(v);
109         ve[v].pb(u);
110     }
111     dfs(1,0);
112     for(ll i=1;i<=n;i++){
113         cout<<tree[root[i]].ans<<" ";
114     }
115 }
116 /*
117 4
118 1 2 3 4
119 1 2
120 2 3
121 3 4
122 */
View Code
原文地址:https://www.cnblogs.com/Fighting-sh/p/10883701.html