zoukankan      html  css  js  c++  java
  • 线段树合并 || BZOJ 5457: 城市

    题面:https://www.lydsy.com/JudgeOnline/problem.php?id=5457

    题解:

    线段树合并,对于每个节点维护sum(以该节点为根的子树中最大的种类和)和kind(以该节点为根的子树中种类和最大的种类)即可。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=(4e5)+50;
     7 int N,M,U,V,num_edge=0,edge_head[maxn],root[maxn];
     8 int num_treenode=0;
     9 struct Edge{int to,nx;}edge[maxn<<1];
    10 inline void Add_edge(int from,int to){
    11     edge[++num_edge].nx=edge_head[from];
    12     edge[num_edge].to=to;
    13     edge_head[from]=num_edge;
    14     return;
    15 }
    16 struct Tree{int lc,rc,l,r,sum,kd;}tr[maxn*20];
    17 inline void Pushup(int x){
    18     int lc=tr[x].lc,rc=tr[x].rc;
    19     if(tr[lc].sum>=tr[rc].sum){
    20         tr[x].sum=tr[lc].sum;
    21         tr[x].kd=tr[lc].kd;
    22     }
    23     else {
    24         tr[x].sum=tr[rc].sum;
    25         tr[x].kd=tr[rc].kd;
    26     }
    27     return;
    28 }
    29 inline void Build(int x,int l,int r,int q,int s){
    30     tr[x].l=l;tr[x].r=r;int mid=(l+r)>>1;
    31     if(l==r&&l==q){
    32         tr[x].kd=q;
    33         tr[x].sum=s;
    34         return;
    35     }
    36     if(q<=mid)Build(tr[x].lc=++num_treenode,l,mid,q,s);
    37     else Build(tr[x].rc=++num_treenode,mid+1,r,q,s);
    38     Pushup(x);
    39     return;
    40 }
    41 struct A_{int kd,sum;}A[maxn];
    42 inline int Merge(int u,int v){
    43     if(!u)return v;
    44     if(!v)return u;
    45     int l=tr[u].l,r=tr[u].r;
    46     if(l==r){
    47         tr[u].sum+=tr[v].sum;
    48         return u;
    49     }
    50     tr[u].lc=Merge(tr[u].lc,tr[v].lc);
    51     tr[u].rc=Merge(tr[u].rc,tr[v].rc);
    52     Pushup(u);
    53     return u;
    54 }
    55 inline void Dfs(int x,int fa){
    56     for(int i=edge_head[x];i;i=edge[i].nx){
    57         int y=edge[i].to;
    58         if(y!=fa){
    59             Dfs(y,x);
    60             Merge(root[x],root[y]);
    61         }
    62     }
    63     return;
    64 }
    65 int main(){
    66     scanf("%d%d",&N,&M);
    67     for(int i=1;i<N;i++){
    68         scanf("%d%d",&U,&V);
    69         Add_edge(U,V);Add_edge(V,U);
    70     }
    71     for(int i=1;i<=N;i++){
    72         scanf("%d%d",&A[i].kd,&A[i].sum);
    73         Build(root[i]=++num_treenode,1,M,A[i].kd,A[i].sum);
    74     }
    75     Dfs(1,0);
    76     for(int i=1;i<=N;i++)printf("%d %d
    ",tr[root[i]].kd,tr[root[i]].sum);
    77     return 0;
    78 }

    By:AlenaNuna

  • 相关阅读:
    SQL慢查询安装过程
    grafana + influxdb + telegraf , 构建性能监控平台
    JDK安装、java环境配置
    多源最短路Floyd 算法————matlab实现
    单源最短路Dijkstra算法——matlab实现
    Layout基本属性总结
    Scrollview中嵌套ListView(自定义组件解决)
    SQL 一列拆分多行
    C# 在异步中使用HttpWebRequest出现的“正在终止线程”错误的解决方案
    sqlserver中分区函数 partition by与 group by 区别 删除关键字段重复列
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/10526299.html
Copyright © 2011-2022 走看看