点此看题面

大致题意: 一棵树上每个点有颜色\(a_i\)和权值\(b_i\),求以每个点为根的子树内权值和最大的颜色及其权值和。

线段树合并

这是一道线段树合并板子题。

(关于线段树合并,可参考我的这篇博客

考虑一开始对于每个叶节点,在线段树第\(a_i\)位插入\(b_i\)。

然后,对于每个非叶节点,在其子节点求完答案后,依次合并其子节点的线段树,再在线段树第\(a_i\)位加上\(b_i\)。

重复此过程即可求出答案。

注意当有多种颜色权值和相同时输出编号最小的颜色,一开始判错\(WA\)了好几发。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 400000
#define LN 20
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
#define mp make_pair
#define fir first
#define sec second
using namespace std;
int n,m,ee,a[N+5],b[N+5],lnk[N+5],Rt[N+5],ans1[N+5],ans2[N+5];
struct edge {int to,nxt;}e[N<<1];typedef pair<int,int> Pr;
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define pc(c) (C==E&&(clear(),0),*C++=c)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
public:
I FastIO() {A=B=FI,C=FO,E=FO+FS;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
Tp I void write(Con Ty& x,Con char& y) {write(x),pc(y);}
I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
}F;
class SegmentTree//动态开点线段树
{
private:
int tot,S[N*LN+5][2];Pr Mx[N*LN+5];
I void PU(CI x)//上传信息
{
if(Mx[S[x][0]].fir^Mx[S[x][1]].fir) Mx[x]=Mx[S[x][0]].fir>Mx[S[x][1]].fir?Mx[S[x][0]]:Mx[S[x][1]];//如果权值和不同,取权值和较大的
else Mx[x]=Mx[S[x][0]].sec<Mx[S[x][1]].sec?Mx[S[x][0]]:Mx[S[x][1]];//否则,取编号较小的
}
public:
I void Merge(CI l,CI r,int& x,CI y)//线段树合并
{
if(!x||!y) return (void)(x+=y);if(l==r) return (void)(Mx[x].fir+=Mx[y].fir);
RI mid=l+r>>1;Merge(l,mid,S[x][0],S[y][0]),Merge(mid+1,r,S[x][1],S[y][1]),PU(x);
}
I void Update(CI l,CI r,int& rt,CI x,CI v)//修改
{
if(!rt&&(rt=++tot),l==r) return (void)(Mx[rt]=mp(Mx[rt].fir+v,l));
RI mid=l+r>>1;x<=mid?Update(l,mid,S[rt][0],x,v):Update(mid+1,r,S[rt][1],x,v),PU(rt);
}
I Pr Query(CI rt) {return Mx[rt];}//询问
}S;
I void dfs(CI x,CI lst)//dfs遍历树
{
RI i;for(i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&(dfs(e[i].to,x),S.Merge(1,m,Rt[x],Rt[e[i].to]),0);//合并子节点的线段树
S.Update(1,m,Rt[x],a[x],b[x]);Pr t=S.Query(Rt[x]);ans1[x]=t.sec,ans2[x]=t.fir;//插入自身信息,并询问求出答案
}
int main()
{
RI i,x,y;for(F.read(n,m),i=1;i^n;++i) F.read(x,y),add(x,y),add(y,x);//读入并建边
for(i=1;i<=n;++i) F.read(a[i],b[i]);//读入数据
for(dfs(1,0),i=1;i<=n;++i) F.write(ans1[i],' '),F.write(ans2[i],'\n');//输出答案
return F.clear(),0;
}

【BZOJ5457】城市(线段树合并)的更多相关文章

  1. BZOJ:5457: 城市(线段树合并)(尚待优化)

    5457: 城市 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 18  Solved: 12[Submit][Status][Discuss] Des ...

  2. BZOJ #5457: 城市 [线段树合并]

    线段树合并的板子题,每次从下到上合并就完事了 // by Isaunoya #include <bits/stdc++.h> using namespace std; #define re ...

  3. 2019.01.19 bzoj5457: 城市(线段树合并)

    传送门 线段树合并菜题. 题意简述:给一棵树,每个节点有bib_ibi​个aia_iai​民族的人,问对于每棵子树,子树中哪个民族的人最多,有多少人. 思路: 直接上线段树合并,边合并边维护答案即可. ...

  4. 线段树合并 || BZOJ 5457: 城市

    题面:https://www.lydsy.com/JudgeOnline/problem.php?id=5457 题解: 线段树合并,对于每个节点维护sum(以该节点为根的子树中最大的种类和)和kin ...

  5. [XJOI NOI2015模拟题13] C 白黑树 【线段树合并】

    题目链接:XJOI - NOI2015-13 - C 题目分析 使用神奇的线段树合并在 O(nlogn) 的时间复杂度内解决这道题目. 对树上的每个点都建立一棵线段树,key是时间(即第几次操作),动 ...

  6. [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

    题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...

  7. BZOJ 3307: 雨天的尾巴( LCA + 线段树合并 )

    路径(x, y) +z : u处+z, v处+z, lca(u,v)处-z, fa(lca)处-z, 然后dfs一遍, 用线段树合并. O(M log M + M log N). 复杂度看起来不高, ...

  8. BZOJ2733 [HNOI2012]永无乡 【线段树合并】

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  9. bzoj 2243 [SDOI2011]染色(树链剖分+线段树合并)

    [bzoj2243][SDOI2011]染色 2017年10月20日 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询 ...

随机推荐

  1. docker /var/lib/docker/aufs/mnt 目录满了怎么清理

    1.创建脚本文件 vi cleandocker.sh 内容如下: #!/bin/sh echo "==================== start clean docker contai ...

  2. 阿里Nacos-配置-多环境

    多环境的配置隔离是配置中心最基础的一个功能之一.不同的环境配置的值不一样,比如数据库的信息,业务的配置等. Spring Boot 多环境配置 首先我们来回顾下在Spring Boot中用配置文件的方 ...

  3. python集合、元组、字典

    主要内容: 2.集合 3.元组 4.字典 复习: 字符串和元组一样,只能读不能写.列表和字典可以嵌套任何东西,列表可以嵌套列表 L = list("hello")  # L = [ ...

  4. C语言程序设计100例之(3): Cantor表

    例3    Cantor表 题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1  1/2  1/3  1/4  …… 2/1 ...

  5. window.onload在文档加载完成后执行

    验证a .b两点疑惑: a.<script src="./main.js"></script>中的window.onload是在html全部加载完了才执行, ...

  6. C# WinForm实现禁止最大化、最小化、双击标题栏、双击图标等操作

    protected override void WndProc(ref Message m) { if (m.Msg==0x112) { switch ((int) m.WParam) { //禁止双 ...

  7. python基础(8):基本数据类型三(dict)、is和==、编码和解码

    1. 字典 1.1 字典的介绍 字典(dict)是python中唯一的一个映射数据类型,它是以{}括起来的键值对组成.在dict中key是唯一的,在保存的时候,根据key来计算出一个内存地址,然后将k ...

  8. python中13个实用的文件操作

    1. 判断指定目录是否存在: os.path.exists(input_folder) 2. 判断指定目录是不是文件夹 os.path.isdir(input_folder) 3. 判断指定目录是不是 ...

  9. Redis缓存系列

    一.缓存雪崩 缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了, ...

  10. react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面

    一.前言 9月,又到开学的季节.为每个一直默默努力的自己点赞!最近都沉浸在react native原生app开发中,之前也有使用vue/react/angular等技术开发过聊天室项目,另外还使用RN ...