Description

N个点,形成一个树状结构。有M次发放,每次选择两个点x,y
对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成
所有发放后,每个点存放最多的是哪种物品。

Input

第一行数字N,M
接下来N-1行,每行两个数字a,b,表示a与b间有一条边
再接下来M行,每行三个数字x,y,z.如题

Output

输出有N行
每i行的数字表示第i个点存放最多的物品是哪一种,如果有
多种物品的数量一样,输出编号最小的。如果某个点没有物品
则输出0

看到对树上路径进行操作,(以蒟蒻博主目前的知识水平)无非两个选择,树剖/树上差分

但是最后只询问一次的话差分会是更好的选择

而且我们要进行的操作并非只是对点的权值进行更改,而是对于每个点插入新的权值并统计出众数

这时候应该想到在每一个节点建权值线段树来维护信息

这样差分的操作就利用权值线段树的插入操作解决了

然鹅在最后统计的时候要合并子树信息

所以还需要线段树合并

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=;
int n,m,to[N<<],nxt[N<<],head[N],tot=;
int size[N*],type,root[N],ls[N*],rs[N*],fa[N][],dep[N],now[N*],ans[N];
void add(int x,int y)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>'')
{if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')
{x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
void dfs(int x,int deep)
{
dep[x]=deep;
for(int i=;i<=;i++)
fa[x][i]=fa[fa[x][i-]][i-];
for(int i=head[x];i;i=nxt[i])
{
if(dep[to[i]])continue;
fa[to[i]][]=x;
dfs(to[i],deep+);
}
}
int lca(int x,int y)
{
if(dep[x]>dep[y])swap(x,y);
for(int i=;i>=;i--)
if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
if(x==y)return x;
for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][];
}
void up(int x)
{
if(size[ls[x]]>=size[rs[x]])
{
size[x]=size[ls[x]];
now[x]=now[ls[x]];
}
else
{
size[x]=size[rs[x]];
now[x]=now[rs[x]];
}
}
void update(int &k,int l,int r,int val,int num)
{
if(!k)k=++type;
if(l==r)
{
size[k]+=num;
now[k]=l;
return ;
}
int mid=l+r>>;
if(val<=mid)update(ls[k],l,mid,val,num);
else update(rs[k],mid+,r,val,num);
up(k);
return ;
}
int Merge(int x,int y,int l,int r)
{
if(!x||!y)return x+y;
if(l==r)
{
size[x]=size[x]+size[y];
now[x]=l;
return x;
}
int mid=l+r>>;
ls[x]=Merge(ls[x],ls[y],l,mid);
rs[x]=Merge(rs[x],rs[y],mid+,r);
up(x);
return x;
}
void cacl(int x)
{
for(int i=head[x];i;i=nxt[i])
{
if(to[i]==fa[x][])continue;
cacl(to[i]);
root[x]=Merge(root[x],root[to[i]],,N-);
}
if(now[root[x]])ans[x]=now[root[x]];
else ans[x]=;
}
int main()
{
n=read();m=read();
for(int i=;i<n;i++)
{
int x=read(),y=read();
add(x,y);add(y,x);
}
dfs(,);
for(int i=;i<=m;i++)
{
int x=read(),y=read(),z=read();
int LCA=lca(x,y);//cout<<"///"<<LCA<<endl;
update(root[x],,N-,z,);
update(root[y],,N-,z,);
update(root[LCA],,N-,z,-);
update(root[fa[LCA][]],,N-,z,-);
}
cacl();
for(int i=;i<=n;i++)printf("%d\n",ans[i]);
return ;
}
 

bzoj3307 雨天的尾巴 题解(线段树合并+树上差分)的更多相关文章

  1. BZOJ_3307_雨天的尾巴_线段树合并+树上差分

    BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...

  2. Bzoj 3307 雨天的尾巴(线段树合并+树上差分)

    C. 雨天的尾巴 题目描述 N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式 第 ...

  3. [bzoj3307]雨天的尾巴_线段树合并

    雨天的尾巴 bzoj-3307 题目大意:N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. ...

  4. 雨天的尾巴(bzoj3307)(线段树合并+树上差分)

    \(N\)个点,形成一个树状结构.有\(M\)次发放,每次选择两个点\(x,y\) 对于\(x\)到\(y\)的路径上(含\(x,y\))每个点发一袋\(Z\)类型的物品.完成 所有发放后,每个点存放 ...

  5. P4556 [Vani有约会]雨天的尾巴 (线段树合并)

    P4556 [Vani有约会]雨天的尾巴 题意: 首先村落里的一共有n座房屋,并形成一个树状结构.然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋 ...

  6. 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). 复杂度看起来不高, ...

  7. P4556 [Vani有约会]雨天的尾巴(线段树合并+lca)

    P4556 [Vani有约会]雨天的尾巴 每个操作拆成4个进行树上差分,动态开点线段树维护每个点的操作. 离线处理完向上合并就好了 luogu倍增lca被卡了5分.....于是用rmq维护.... 常 ...

  8. P4556 [Vani有约会]雨天的尾巴(线段树合并)

    传送门 一道线段树合并 首先不难看出树上差分 我们把每一次修改拆成四个,在\(u,v\)分别放上一个,在\(lca\)和\(fa[lca]\)各减去一个,那么只要统计一下子树里的总数即可 然而问题就在 ...

  9. 洛谷P4556 雨天的尾巴(线段树合并)

    洛谷P4556 雨天的尾巴 题目链接 题解: 因为一个点可能存放多种物品,直接开二维数组进行统计时间.空间复杂度都不能承受.因为每一个点所拥有的物品只与其子树中的点有关,所以可以考虑对每一个点来建立一 ...

随机推荐

  1. 哈希表的C实现(一)

    哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.具体的介绍网上有很详 ...

  2. Linux网络编程笔记(修订版)

    我的网络编程笔记, 因为最近又要做Linux下的网络编程,故重新修订, 其中一些内容参考了文末的链接及文章 1.   基本概念 2.   基本接口 2.1.   打开一个socket 2.2.   将 ...

  3. 监听屏幕旋转事件window. onorientationchange

    // 判断屏幕是否旋转 function orientationChange() { switch(window.orientation) { case 0: alert("肖像模式 0,s ...

  4. vs 2015 community Blend和devenv启动的区别

    使用Blend启动会有部分功能无法显示 如:SVN管理插件,工具栏 使用devenv启动会全部显示

  5. Thrift 使用TNonblockingServer模型时调用PosixThreadFactory出错。

    Thrift 使用TNonblockingServer模型时调用PosixThreadFactory出错.   我定位到shared_ptr<PosixThreadFactory> thr ...

  6. C++笔试题库之编程、问答题 300~305道

    301. 以下代码有什么问题? cout << (true?1:”1″) << endl; 答:三元表达式“?:”问号后面的两个操作数必须为同一类型. 302.以下代码能够编译 ...

  7. WPF 加载 WINFORM控件 异常: 调度程序进程已挂起,但消息仍在处理中

    在加载TradeAtServer的统计中的 单个合约盈亏情况 异常:,调度程序进程已挂起,但消息仍在处理中 发现可能是属性设置引发的问题 比如DateTimePikcer.Value+= set, g ...

  8. bzoj 3745: [Coci2015]Norma【分治】

    参考:https://blog.csdn.net/lych_cys/article/details/51203960 真的不擅长这种-- 分治,对于一个(l,r),先递归求出(l,mid),(mid+ ...

  9. P2579 [ZJOI2005]沼泽鳄鱼

    传送门 话说邻接矩阵居然还能快速幂的么-- 把原图的邻接矩阵\(G\)打出来,那么\(G[u][v]\)表示一秒后\(u\)到\(v\)的方案数,\(G^2[u][v]\)表示\(2\)秒后的方案数- ...

  10. Jquery Validate不是用submit按钮提交表单,使用a标签js代码都可以

    不多说,上代码. $("#form").validate(); $("#btn").click(function() { if($("#form&qu ...