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. python之dic {字典}(重要指数*****)

    1. 什么是字典 {'name': '汪峰', 'age': 18} '键':'值' 别的语言键值对数据 键: 必须是可哈希(不可变的数据类型),并且是唯一的 值: 任意 可以保存任意类型的数据 字典 ...

  2. 打印两个有序链表的公共部分 【题目】 给定两个有序链表的头指针head1和head2,打印两个 链表的公共部分

    简单题 package my_basic.class_3; public class Code_10_PrintCommonPart { public static class Node{ int v ...

  3. shell脚本,awk实现文件a的每行数据与文件b的相对应的行的值相减,得到其绝对值。

    解题思路 文件 shu 是下面这样的.220 34 50 70553 556 32 211 1 14 98 33 文件 jian是下面这样的.1082 想要得到结果是下面这样的.210 24 40 6 ...

  4. Swift 编程思想 Part 4:map all the things!

    Swift 编程思想 Part 4:map all the things! 2015-10-22  837 文章目录 1. 数组 vs. 可选类型 2. 作用在可选类型上的 map() 3. 回到我们 ...

  5. Luogu P2123 皇后游戏(贪心)

    题目链接:P2123 皇后游戏 如果证明这个题为什么是贪心的话,我是不会的,但是一看这个题目就是一个贪心,然后满足贪心的性质: 都能从两个人(东西)扩展到n个人(东西) 一定能从相邻状态扩展到不相邻的 ...

  6. POJ-3669-流星雨

    这题的话,卡了有两个小时左右,首先更新地图的时候越界了,我们进行更新的时候,要判断一下是不是小于零了,越界就会Runtime Error. 然后bfs 的时候,我没有允许它搜出300以外的范围,然后就 ...

  7. HDU-1009-肥鼠交易

    这题是一道简单的可拆分的贪心题目,需要注意的是,我们定义的结构体里面都应该用double类型, 或者float类型,不然两个int相除,就失去了精度(强转也可以). #include <cstd ...

  8. 【php】 给数组重建索引

    array_values $a = [1,2]; unset($a[1]); $a[] = 3; print_r($a); // 输出 [0=>1,2=>3]

  9. mysql函数总结

    MySQL函数 MySQL数据库提供了很多函数包括: 数学函数:字符串函数:日期和时间函数:条件判断函数:系统信息函数:加密函数:格式化函数: 一.数学函数 数学函数主要用于处理数字,包括整型.浮点数 ...

  10. 日志logging

    日志: 日志分为5个级别:debug(10),info(20),warning(30),error(40),critical(50) 日志四个组成部分:logger,handler,filter,fo ...