[Vani有约会]雨天的尾巴(树上差分+线段树合并)
首先村落里的一共有n座房屋,并形成一个树状结构。然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋z类型的救济粮。
然后深绘里想知道,当所有的救济粮发放完毕后,每座房子里存放的最多的是哪种救济粮。
Solution
一看到链上操作,最后统计答案,自然而然的想到树上差分,a++ ,b++,lca--,fa[lca]--就可以完成一条链的操作。
但这道题加的东西有好多种类。
所以考虑对每个节点开一颗线段树,每次在对应位置加上。
然后我们DFS的时候,朴素的树上差分直接size[u]+=size[v] (son[u]==v)这回u和v是两颗线段树。
所以用线段数合并就行了。
由于这题涉及大量的线段树,所以我们的数组得开大点。
颜色需要提前离散化。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 100002
using namespace std;
int p[N][],head[N],tot,deep[N],tr[N*],L[N*],R[N*],num[N],rt[N],top,ans[N],toy;
struct zzh{
int n,to;
}e[N<<];
struct bi{
int a,b,d;
}q[N];
inline void add(int u,int v){
e[++tot].n=head[u];
e[tot].to=v;
head[u]=tot;
}
void dfs(int u,int fa){
for(int i=;(<<i)<=deep[u];++i)p[u][i]=p[p[u][i-]][i-];
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa){
int v=e[i].to;p[v][]=u;deep[v]=deep[u]+;
dfs(v,u);
}
}
inline int getlca(int a,int b){
if(deep[a]<deep[b])swap(a,b);
for(int i=;i>=;--i)if(deep[a]-(<<i)>=deep[b])a=p[a][i];
if(a==b)return a;
for(int i=;i>=;--i)if(p[a][i]!=p[b][i])a=p[a][i],b=p[b][i];
return p[a][];
}
void upd(int &cnt,int l,int r,int x,int y){
if(!cnt)cnt=++toy;
if(l==r){
tr[cnt]+=y;
return;
}
int mid=(l+r)>>;
if(mid>=x)upd(L[cnt],l,mid,x,y);
else upd(R[cnt],mid+,r,x,y);
tr[cnt]=max(tr[L[cnt]],tr[R[cnt]]);
}
int query(int &cnt,int l,int r){
if(!tr[cnt]||!cnt)return ;
if(l==r)return num[l];
int mid=(l+r)>>;
if(tr[L[cnt]]>=tr[R[cnt]])return query(L[cnt],l,mid);
else return query(R[cnt],mid+,r);
}
int merge(int &u,int v,int l,int r){
if(!u||!v)return u+v;
if(l==r){
tr[u]+=tr[v];
return u;
}
int mid=(l+r)>>;
L[u]=merge(L[u],L[v],l,mid);
R[u]=merge(R[u],R[v],mid+,r);
tr[u]=max(tr[L[u]],tr[R[u]]);
return u;
}
void dfs2(int u,int fa){
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa){
int v=e[i].to;
dfs2(v,u);
rt[u]=merge(rt[u],rt[v],,top);
}
ans[u]=query(rt[u],,top);
}
int main(){
int n,m,u,v;
scanf("%d%d",&n,&m);
for(int i=;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
dfs(,);
for(int i=;i<=m;++i)scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].d),num[++top]=q[i].d;
sort(num+,num+top+);
top=unique(num+,num+top+)-num-;
for(int i=;i<=m;++i){
q[i].d=lower_bound(num+,num+top+,q[i].d)-num;
int lca=getlca(q[i].a,q[i].b);
upd(rt[q[i].a],,top,q[i].d,);upd(rt[q[i].b],,top,q[i].d,);
upd(rt[lca],,top,q[i].d,-);upd(rt[p[lca][]],,top,q[i].d,-);
}
dfs2(,);
for(int i=;i<=n;++i)printf("%d\n",ans[i]);
return ;
}
[Vani有约会]雨天的尾巴(树上差分+线段树合并)的更多相关文章
- BZOJ 3307 雨天的尾巴 (树上差分+线段树合并)
题目大意:给你一棵树,树上一共n个节点,共m次操作,每次操作给一条链上的所有节点分配一个权值,求所有节点被分配到所有的权值里,出现次数最多的权值是多少,如果出现次数相同就输出最小的. (我辣鸡bzoj ...
- [Vani有约会]雨天的尾巴——树上差分+动态开点线段树合并
题目描述 首先村落里的一共有n座房屋,并形成一个树状结构.然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋z类型的救济粮. 然后深绘里想知道,当所 ...
- [BZOJ3307] 雨天的尾巴(树上差分+线段树合并)
[BZOJ3307] 雨天的尾巴(树上差分+线段树合并) 题面 给出一棵N个点的树,M次操作在链上加上某一种类别的物品,完成所有操作后,要求询问每个点上最多物品的类型. N, M≤100000 分析 ...
- [Luogu5327][ZJOI2019]语言(树上差分+线段树合并)
首先可以想到对每个点统计出所有经过它的链的并所包含的点数,然后可以直接得到答案.根据实现不同有下面几种方法.三个log:假如对每个点都存下经过它的链并S[x],那么每新加一条路径进来的时候,相当于在路 ...
- 2018.08.28 洛谷P4556 [Vani有约会]雨天的尾巴(树上差分+线段树合并)
传送门 要求维护每个点上出现次数最多的颜色. 对于每次修改,我们用树上差分的思想,然后线段树合并统计答案就行了. 注意颜色很大需要离散化. 代码: #include<bits/stdc++.h& ...
- P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并 (树上差分+线段树合并)
显然的树上差分问题,最后要我们求每个点数量最多的物品,考虑对每个点建议线段树,查询子树时将线段树合并可以得到答案. 用动态开点的方式建立线段树,注意离散化. 1 #include<bits/st ...
- bzoj3307 雨天的尾巴 题解(线段树合并+树上差分)
Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后,每个点存放最多的是哪种物品. Input ...
- bzoj 3307: 雨天的尾巴【树剖lca+树上差分+线段树合并】
这居然是我第一次写线段树合并--所以我居然在合并的时候加点结果WAWAWAMLEMLEMLE--!ro的时候居然直接指到la就行-- 树上差分,每个点建一棵动态开点线段树,然后统计答案的时候合并即可 ...
- 【bzoj3307】雨天的尾巴 权值线段树合并
题目描述 N个点,形成一个树状结构.有M次发放,每次选择两个点x,y,对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入 第一行数字N,M接下来 ...
- Luogu5327 ZJOI2019语言(树上差分+线段树合并)
暴力树剖做法显然,即使做到两个log也不那么优美. 考虑避免树剖做到一个log.那么容易想到树上差分,也即要对每个点统计所有经过他的路径产生的总贡献(显然就是所有这些路径端点所构成的斯坦纳树大小),并 ...
随机推荐
- 调整分区大小 转载--------------http://blog.csdn.net/perfectzq/article/details/73606119
centos7重新调整分区大小 centos 7 调整 root 和 home 的容量大小 查看磁盘的空间大小: df -h 备份/home : cp -r /home/ homebak/ 卸载 ...
- 游标cursor案例
- C# Note7:MVVM模式之数据绑定
一.资源说明 (1)本文参考自: 一步步走进WPF的MVVM模式(二):数据绑定 WPF之数据绑定总结 二.正文 数据绑定 (Data Binding)是WPF最重要的特性之一,也是实现 MVVM( ...
- Flutter 中 JSON 解析
本文介绍一下Flutter中如何进行json数据的解析.在移动端开发中,请求服务端返回json数据并解析是一个很常见的使用场景.Android原生开发中,有GsonFormat这样的神器,一键生成Ja ...
- Hbase存储流程
- Eclipse报错:An internal error has occurred. Widget is disposed
win10家庭版报错. 右键Eclipse的快捷方式,在兼容性窗口的兼容模式中,将“以兼容模式运行这个程序”选项打对勾.选择win8就可以解决问题.
- Lodop打印控件设置表格次页偏移
Lodop打印控件有很好的自动分页功能,超文本table表格一页装不下,自动分到第二页,第三页……通常表格之前还会有一些内容,比如标题,制表人名称日期什么的杂七杂八的东西,这种东西会占用一定的空间,这 ...
- npm火速上手
npm,即node package manager,翻译过来就是“node包管理工具”.“node包”是啥呢?它就是jquery啦.bootstrap啦之类的各种版本. 1.npm的安装 第一步,下 ...
- Deconvolution用法
- Using MongoDB with Web API and ASP.NET Core
MongoDB is a NoSQL document-oriented database that allows you to define JSON based documents which a ...