zoukankan      html  css  js  c++  java
  • codeforces 600E . 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
    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

    思路:

    对每个点建线段树在线段树上当前点的权值下标+1,每个点与父节点进行线段树合并,这样对树dfs一遍就可以求出所有的值了。

    实现代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define mid ll m = (l + r) >> 1
    const ll M = 1e5 + 10;
    
    struct node{
        ll ans,sum;
    }tr[M*40];
    
    struct node1{
        ll to,next;
    }e[M<<1];
    ll cnt,head[M],idx,ls[M*40],rs[M*40],root[M],a[M],ans[M];
    
    void add(ll u,ll v){
        e[++cnt].to = v;e[cnt].next = head[u];head[u] = cnt;
    }
    
    void pushup(ll rt){
        if(tr[ls[rt]].sum > tr[rs[rt]].sum){
            tr[rt].sum = tr[ls[rt]].sum;
            tr[rt].ans = tr[ls[rt]].ans;
        }
        else if(tr[ls[rt]].sum == tr[rs[rt]].sum){
            tr[rt].sum = tr[ls[rt]].sum;
            tr[rt].ans = tr[rs[rt]].ans + tr[ls[rt]].ans;
        }
        else{
            tr[rt].sum = tr[rs[rt]].sum;
            tr[rt].ans = tr[rs[rt]].ans;
        }
    }
    
    void update(ll p,ll c,ll l,ll r,ll &rt){
        if(!rt) rt = ++idx;
        if(l == r){
            tr[rt].sum += c;
            tr[rt].ans = l;
            return ;
        }
        mid;
        if(p <= m) update(p,c,l,m,ls[rt]);
        else update(p,c,m+1,r,rs[rt]);
        pushup(rt);
    }
    
    ll Merge(ll x,ll y,ll l,ll r){
        if(!x) return y;
        if(!y) return x;
        if(l == r){
            tr[x].sum += tr[y].sum;
            tr[x].ans = l;
            return x;
        }
        mid;
        ls[x] = Merge(ls[x],ls[y],l,m);
        rs[x] = Merge(rs[x],rs[y],m+1,r);
        pushup(x);
        return x;
    }
    
    void dfs(ll u,ll fa){
        for(ll i = head[u];i;i=e[i].next){
            ll v = e[i].to;
            if(v == fa) continue;
            dfs(v,u);
            Merge(root[u],root[v],1,M);
        }
        update(a[u],1,1,M,root[u]);
        ans[u] = tr[root[u]].ans;
    }
    
    int main()
    {
        ll n,u,v;
        scanf("%lld",&n);
        for(ll i = 1;i <= n;i ++){
            scanf("%lld",&a[i]);
            root[i] = i;
            idx++;
        }
        for(ll i = 1;i < n;i ++){
            scanf("%lld%lld",&u,&v);
            add(u,v); add(v,u);
        }
        dfs(1,0);
        for(ll i = 1;i <= n;i ++){
            printf("%lld ",ans[i]);
        }
        return 0;
    
    }
  • 相关阅读:
    UVA 11925 Generating Permutations 生成排列 (序列)
    UVA 1611 Crane 起重机 (子问题)
    UVA 11572 Unique snowflakes (滑窗)
    UVA 177 PaperFolding 折纸痕 (分形,递归)
    UVA 11491 Erasing and Winning 奖品的价值 (贪心)
    UVA1610 PartyGame 聚会游戏(细节题)
    UVA 1149 Bin Packing 装箱(贪心)
    topcpder SRM 664 div2 A,B,C BearCheats , BearPlays equalPiles , BearSorts (映射)
    UVA 1442 Cave 洞穴 (贪心+扫描)
    UVA 1609 Foul Play 不公平竞赛 (构(luan)造(gao)+递归)
  • 原文地址:https://www.cnblogs.com/kls123/p/9972034.html
Copyright © 2011-2022 走看看