zoukankan      html  css  js  c++  java
  • CF600E:Lomsat gelral(线段树合并)

    Description

    一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和。

    Input

    第一行一个$n$。第二行$n$个数字是$c[i]$。后面$n-1$行给出树边。

    Output

    一行答案。

    Sample Input1

    4
    1 2 3 4
    1 2
    2 3
    2 4

    Sample Output1

    10 9 3 4

    Sample Input2

    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

    Sample Output2

    6 5 4 3 2 3 3 1 1 3 2 2 1 2 3

    Solution

    线段树合并模板题,但我竟然读错题了QAQ……
    情况特殊所以$Merge$的时候要加上$l$,$r$。
    没啥好说的看代码就能懂……

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define N (100009)
     5 #define LL long long
     6 using namespace std;
     7 
     8 struct Sgt{int ls,rs,max; LL val;}Segt[N*50];
     9 struct Edge{int to,next;}edge[N<<1];
    10 int n,x,u,v,sgt_num,c[N],Root[N];
    11 int head[N],num_edge;
    12 
    13 void add(int u,int v)
    14 {
    15     edge[++num_edge].to=v;
    16     edge[num_edge].next=head[u];
    17     head[u]=num_edge;
    18 }
    19 
    20 void Pushup(int now)
    21 {
    22     int ls=Segt[now].ls, rs=Segt[now].rs;
    23     if (Segt[ls].max==Segt[rs].max)
    24     {
    25         Segt[now].max=Segt[ls].max;
    26         Segt[now].val=Segt[ls].val+Segt[rs].val;
    27     }
    28     else if (Segt[ls].max>Segt[rs].max)
    29     {
    30         Segt[now].max=Segt[ls].max;
    31         Segt[now].val=Segt[ls].val;
    32     }
    33     else
    34     {
    35         Segt[now].max=Segt[rs].max;
    36         Segt[now].val=Segt[rs].val;
    37     }
    38 }
    39 
    40 void Update(int &now,int l,int r,int v)
    41 {
    42     if (!now) now=++sgt_num;
    43     if (l==r)
    44     {
    45         Segt[now].max=1;
    46         Segt[now].val=v;
    47         return;
    48     }
    49     int mid=(l+r)>>1;
    50     if (v<=mid) Update(Segt[now].ls,l,mid,v);
    51     else Update(Segt[now].rs,mid+1,r,v);
    52     Pushup(now);
    53 }
    54 
    55 int Merge(int x,int y,int l,int r)
    56 {
    57     if (!x || !y) {return x|y;}
    58     int tmp=++sgt_num;
    59     if (l==r)
    60     {
    61         Segt[tmp].max=Segt[x].max+Segt[y].max;
    62         Segt[tmp].val=l; return tmp;
    63     }
    64     int mid=(l+r)>>1;
    65     Segt[tmp].ls=Merge(Segt[x].ls,Segt[y].ls,l,mid);
    66     Segt[tmp].rs=Merge(Segt[x].rs,Segt[y].rs,mid+1,r);
    67     Pushup(tmp); return tmp;
    68 }
    69 
    70 void DFS(int x,int fa)
    71 {
    72     for (int i=head[x]; i; i=edge[i].next)
    73         if (edge[i].to!=fa)
    74         {
    75             DFS(edge[i].to,x);
    76             Root[x]=Merge(Root[x],Root[edge[i].to],1,n);
    77         }
    78 }
    79 
    80 int main()
    81 {
    82     scanf("%d",&n);
    83     for (int i=1; i<=n; ++i)
    84     {
    85         scanf("%d",&c[i]);
    86         Update(Root[i],1,n,c[i]);
    87     }
    88     for (int i=1; i<=n-1; ++i)
    89     {
    90         scanf("%d%d",&u,&v);
    91         add(u,v); add(v,u);
    92     }
    93     DFS(1,0);
    94     for (int i=1; i<=n; ++i)
    95         printf("%lld ",Segt[Root[i]].val);
    96 }
  • 相关阅读:
    2018-06-15for与数组/for-in与数组/一维二维多维数组
    2018-06-14控制语句for+switch+while循环
    2018-06-13JS分支结构+转义符
    2018-06-12JavaScript基础知识1
    2018-06-11笔记
    2018-06-08CSS常用样式+浮动+定位+盒子模型
    2018-06-06Div+CSS基础理论
    2018-06-05表单结构
    2018-06-04表格结构+表格嵌套
    2018-06-02笔记
  • 原文地址:https://www.cnblogs.com/refun/p/10057599.html
Copyright © 2011-2022 走看看