Lomsat gelral
Lomsat gelral
http://codeforces.com/contest/600/problem/E
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.
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.
Print n integers — the sums of dominating colours for each vertex.
4
1 2 3 4
1 2
2 3
2 4
10 9 3 4
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
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 */
posted on 2019-05-17 21:13 Fighting_sh 阅读(245) 评论(0) 编辑 收藏 举报