bzoj 5457 城市

题目大意

给定一棵以\(1\)为根的\(n\)个节点的有根树。

每个节点有一个民族和该民族在当前节点的人数。

有\(n\)个询问,第\(i\)个询问是求以\(i\)为根的子树内,人数最多的民族是哪个,这个民族有多少人。

如果最多的民族有多个输出编号最小的。

数据范围

\(1\le n\le 4\cdot 10^5\),\(m\le n\),\(1\le a_i\le m\),\(0\le b_i\le 1000\)。

题解

我们发现这个题满足一个性质,就是无修改、询问子树。

然后不难发现,这个题就是维护一个桶然后求编号最小的最大值,这东西显然可以合并啊。

好,无修改询问子树可合并,我们就考虑考虑\(dsu\ on\ tree\)。

想到\(dsu\ on\ tree\)这题就切掉了啊。

只需要维护一个每棵子树维护一个桶就好了。

代码

#include <bits/stdc++.h>
#define N 400010
using namespace std;
int to[N<<1],head[N],nxt[N<<1],tot;
int st[N],a[N],b[N],size[N],son[N],ans_num[N],ans_id[N];
int mx,id;
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
inline void add(int x,int y) {to[++tot]=y; nxt[tot]=head[x]; head[x]=tot;}
void dfs1(int p,int fa)
{
size[p]=1;
for(int i=head[p];i;i=nxt[i]) if(to[i]!=fa)
{
dfs1(to[i],p);
size[p]+=size[to[i]];
if(size[to[i]]>size[son[p]]) son[p]=to[i];
}
}
void add(int p,int fa,int val)
{
st[a[p]]+=val*b[p];
if(st[a[p]]==mx&&a[p]<id) id=a[p];
else if(st[a[p]]>mx) mx=st[a[p]],id=a[p];
for(int i=head[p];i;i=nxt[i]) if(to[i]!=fa) add(to[i],p,val);
}
void dfs2(int p,int fa,int opt)
{
for(int i=head[p];i;i=nxt[i]) if(to[i]!=fa&&to[i]!=son[p]) dfs2(to[i],p,0);
if(son[p]) dfs2(son[p],p,1);
for(int i=head[p];i;i=nxt[i]) if(to[i]!=fa&&to[i]!=son[p]) add(to[i],p,1);
st[a[p]]+=b[p];
if(st[a[p]]==mx&&a[p]<id) id=a[p];
else if(st[a[p]]>mx) mx=st[a[p]],id=a[p];
ans_num[p]=mx,ans_id[p]=id;
if(!opt) add(p,fa,-1),mx=id=0;
}
int main()
{
int n=rd(),m=rd();
for(int i=1;i<n;i++) {int x=rd(),y=rd(); add(x,y),add(y,x);}
for(int i=1;i<=n;i++) a[i]=rd(),b[i]=rd();
dfs1(1,1); dfs2(1,1,1);
for(int i=1;i<=n;i++) printf("%d %d\n",ans_id[i],ans_num[i]);
return 0;
}

小结

\(dsu\ on\ tree\)的题目都有点小明显。

而且我们发现,这鬼东西是不是和点分治有点小像。

其实有些点分治题是完全可以拿这东西跑的。

算是黑科技吧,还是很好用的。

[bzoj5457]城市_dsu on tree的更多相关文章

  1. 【BZOJ】3091: 城市旅行 Link-Cut Tree

    [题意]参考PoPoQQQ. 给定一棵树,每个点有一个点权,提供四种操作: 1.删除两点之间的连边 不存在边则无视 2.在两点之前连接一条边 两点已经联通则无视 3.在两点之间的路径上所有点的点权加上 ...

  2. bzoj5457 城市

    一棵树,每个点有一个民族,和一个人数,求每个子树里最多的民族及其人数,如果一样,输出编号最小的 $n \leq 500000$ sol: 卡莫队的毒瘤题,需要 dsu on tree 大概就是 dfs ...

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

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

  4. dsu on tree(无讲解)

    CF741D. Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 分析: 最多有一个字符出现奇数次 维护某个状态下深度的最大值,注意 ...

  5. P5471- K-D tree优化建图-弹跳

    P5471- K-D tree优化建图-弹跳 优化建图是一种思想. 题意 有\(n\)个城市分布在小鸟岛上,有\(m\)个弹弓分布在这些城市里.因为弹弓体积大,固定麻烦,所以每个弹弓只能把小鸟弹飞到一 ...

  6. Hibernate 基础配置及常用功能(二)

    本章主要是描述几种经典映射关系,顺带比较Hibernate4.x和Hibernate5.x之间的区别. 一.建立测试工程目录 有关实体类之间的相互映射关系,Hibernate官方文档其实描述的非常详细 ...

  7. 070.Python聚焦爬虫数据解析

    一 聚焦爬虫数据解析 1.1 基本介绍 聚焦爬虫的编码流程 指定url 基于requests模块发起请求 获取响应对象中的数据 数据解析 进行持久化存储 如何实现数据解析 三种数据解析方式 正则表达式 ...

  8. 【BZOJ5457】城市(线段树合并)

    点此看题面 大致题意: 一棵树上每个点有颜色\(a_i\)和权值\(b_i\),求以每个点为根的子树内权值和最大的颜色及其权值和. 线段树合并 这是一道线段树合并板子题. (关于线段树合并,可参考我的 ...

  9. [BZOJ3754]Tree之最小方差树

    3754: Tree之最小方差树 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 402  Solved: 152[Submit][Status][Di ...

随机推荐

  1. (5)JSTL的xml标签库

    Jstl的XML标签库 JSTL提供了操作xml文件的标签库,使用xml标签库可以省去使用Dom和SAX标签库的繁琐,能轻松的读取xml文件的内容. <%@ taglib uri="h ...

  2. node爬虫(简版)

    做node爬虫,首先像如何的去做这个爬虫,首先先想下思路,我这里要爬取一个页面的数据,要调取网页的数据,转换成页面格式(html+div)格式,然后提取里面独特的属性值,再把你提取的值,传送给你的页面 ...

  3. [LUOGU] P1063 能量项链

    题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定 ...

  4. RestTemplate进行表单请求,注意要使用MultiValueMap

    在对接API的时候,有时候文档中会说,表单提交,这时候就需要用到 MultiValueMap来操作,下面给大家展示一个简单的demo. MultiValueMap<Object, Object& ...

  5. 九:SQL之DQL数据查询语言多表操作

    前言: 一:数据准备 员工表emp 和部门表 dept 注意:我在录入员工表的时候,特意添加了两条没有部门的员工,他们的部门id对应为null; --分别创建部门和员工表,并实现一对多关系 DROP ...

  6. 如何删除SQL Server 2014连接到服务器中的服务器名称

    查看了网上的一些方法,均是以前版本的处理方法,不过原理都是删除"SqlStudio.bin",通过“Everything”搜索SqlStudio.bin,位置是: C:\Users ...

  7. js事件,操作页面文档,计算后样式,数据类型

    js:运行在浏览器的脚本语言 js引入 1.行间式:存在于行间事件中 <div id="div" onclick="this.style.color="r ...

  8. LeetCode(136) Single Number

    题目 Given an array of integers, every element appears twice except for one. Find that single one. Not ...

  9. C++中 #ifdef 和#endif的作用

    一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是"条件编译".有时,希望当满足某条件时对一组 ...

  10. cygin常用命令

    基本操作命令: ---------------------------------------------------------------------- --------------------- ...