• 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
  • 相关阅读:
    《深入浅出WPF》4.0x名称空间
    《深入浅出WPF》3.0 XAML语法
    DataGridview 自动切换到 下一行
    C# 生成条形码图片,效果不错
    将DataTable 导出为csv
    DataTable,DataGridVIew转换到xls 方法 (转)
    NPOI读取Excel 数据 转。。。
    修改 字段大小
    VC
    统计每天 指定 时间段内 的数据
  • 原文地址:https://www.cnblogs.com/Fighting-sh/p/10883701.html
Copyright © 2020-2023  润新知