zoukankan      html  css  js  c++  java
  • CF600E Lomsat gelral (启发式合并)

    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
    4
    1 2 3 4
    1 2
    2 3
    2 4
    Output
    10 9 3 4
    Input
    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
    6 5 4 3 2 3 3 1 1 3 2 2 1 2 3


    题解:题意就是定义一个节点的优势点为他的子树中出现次数最多的数字,(可能会有多个优势点),让你求每一个点的优势点的和;
    可以用map记录每一个点的各个优势点,记录每点的子树中每个数字出现的次数,然后dfs。
    参考代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define clr(a,val) memset(a,val,sizeof(a))
     4 #define pb push_back
     5 #define fi first
     6 #define se second
     7 typedef long long ll;
     8 const int maxn=1e5+10;
     9 int n,cnt;
    10 int col[maxn],head[maxn],dy[maxn];
    11 ll ans[maxn];
    12 struct Edge{
    13     int to,nxt;
    14 } edge[maxn<<1];
    15 map<int,int> mp[maxn];
    16 map<int,ll> sum[maxn];
    17 map<int,int>::iterator it1,it2;
    18 inline int read()
    19 {
    20     int x=0,f=1;char ch=getchar();
    21     while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();} 
    22     while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    23     return x*f;
    24 }
    25 
    26 inline void addedge(int u,int v)
    27 {
    28     edge[cnt].to=v;
    29     edge[cnt].nxt=head[u];
    30     head[u]=cnt++;
    31 }
    32 
    33 inline void dfs(int u,int fa)
    34 {
    35     for(int e=head[u];~e;e=edge[e].nxt)
    36     {
    37         int v=edge[e].to;
    38         if(v==fa) continue;
    39         dfs(v,u);
    40         if(mp[dy[u]].size()<mp[dy[v]].size()) swap(dy[u],dy[v]);
    41         for(it1=mp[dy[v]].begin();it1!=mp[dy[v]].end();it1++)
    42         {
    43             sum[dy[u]][mp[dy[u]][(*it1).fi]]-=(*it1).fi;
    44             mp[dy[u]][(*it1).fi]+=(*it1).se;
    45             sum[dy[u]][mp[dy[u]][(*it1).fi]]+=(*it1).fi;
    46         }
    47     } 
    48     ans[u]=(*sum[dy[u]].rbegin()).se;
    49 }
    50 
    51 int main()
    52 {
    53     n=read();
    54     for(int i=1;i<=n;++i) col[i]=read(),dy[i]=i,mp[i][col[i]]=1,sum[i][1]=col[i];
    55     int u,v;cnt=0;clr(head,-1);
    56     for(int i=1;i<n;++i) 
    57     {
    58         u=read();v=read();
    59         addedge(u,v);addedge(v,u);
    60     }
    61     dfs(1,0);
    62     for(int i=1;i<=n;++i) printf("%lld%c",ans[i],i==n? '
    ':' ');
    63     
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    设置导航条上的主题一颜色
    luogu_2158【题解】欧拉函数
    luogu_1313【题解】二项式定理
    【数论学习笔记】高斯消元
    luogu_2524【题解】康托展开
    luogu_1495【题解】中国剩余定理
    【数论学习笔记】 约数
    luogu_4430 luogu_4981【题解】 Cayley定理
    【数论学习笔记】质数
    【数论学习笔记】同余
  • 原文地址:https://www.cnblogs.com/csushl/p/10293301.html
Copyright © 2011-2022 走看看