首先村落里的一共有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][21],head[N],tot,deep[N],tr[N*50],L[N*50],R[N*50],num[N],rt[N],top,ans[N],toy;
struct zzh{int n,to;
}e[N<<1];
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=1;(1<<i)<=deep[u];++i)p[u][i]=p[p[u][i-1]][i-1];for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa){int v=e[i].to;p[v][0]=u;deep[v]=deep[u]+1;dfs(v,u);}
}
inline int getlca(int a,int b){if(deep[a]<deep[b])swap(a,b);for(int i=20;i>=0;--i)if(deep[a]-(1<<i)>=deep[b])a=p[a][i];if(a==b)return a;for(int i=20;i>=0;--i)if(p[a][i]!=p[b][i])a=p[a][i],b=p[b][i];return p[a][0];
}
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)>>1;if(mid>=x)upd(L[cnt],l,mid,x,y);else upd(R[cnt],mid+1,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 0;if(l==r)return num[l];int mid=(l+r)>>1;if(tr[L[cnt]]>=tr[R[cnt]])return query(L[cnt],l,mid);else return query(R[cnt],mid+1,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)>>1;L[u]=merge(L[u],L[v],l,mid);R[u]=merge(R[u],R[v],mid+1,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],1,top);}ans[u]=query(rt[u],1,top);
}
int main(){int n,m,u,v;scanf("%d%d",&n,&m);for(int i=1;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);dfs(1,0);for(int i=1;i<=m;++i)scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].d),num[++top]=q[i].d;sort(num+1,num+top+1);top=unique(num+1,num+top+1)-num-1;for(int i=1;i<=m;++i){q[i].d=lower_bound(num+1,num+top+1,q[i].d)-num;int lca=getlca(q[i].a,q[i].b);upd(rt[q[i].a],1,top,q[i].d,1);upd(rt[q[i].b],1,top,q[i].d,1);upd(rt[lca],1,top,q[i].d,-1);upd(rt[p[lca][0]],1,top,q[i].d,-1);}dfs2(1,0);for(int i=1;i<=n;++i)printf("%d\n",ans[i]);return 0;
}

转载于:https://www.cnblogs.com/ZH-comld/p/9668780.html

[Vani有约会]雨天的尾巴(树上差分+线段树合并)相关推荐

  1. 洛谷 - P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并(树上差分+线段树合并)

    题目链接:点击查看 题目大意:给出一棵树,再给出 m 次操作,每次操作会选择两个点 ( x , y ) ,使得这条路径上的所有点的种类 z 加一,最后问每个点的哪个种类出现的频率最高,若多个种类出现频 ...

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

    题目链接 Solution 树上差分+线段树合并. 在每个节点上维护一棵权值线段树. 然后如果需要修改 \(x,y\) 两点,则在 \(x\) 处和 \(y\) 处分别加上 \(1\) 的权值. 然后 ...

  3. 线段树分裂与合并 ---- 树上差分 P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并

    题目链接 解题思路: 首先题目是对u,vu,vu,v这两条路径上面添加一个zzz,然后运用树上点的差分思想,对于分发路径u,vu,vu,v,我们在uuu上+1+1+1,在vvv上+1+1+1,在lca ...

  4. 洛咕 P4556 [Vani有约会]雨天的尾巴

    终于把考试题清完了...又复活了... 树上差分,合并用线段树合并,但是空间会炸. 某大佬:lca和fa[lca]减得时候一定已经存在这个节点了,所以放进vector里,合并完之后减掉就好了... 玄 ...

  5. 【线段树合并】解题报告:luogu P4556雨天的尾巴 (树上对点差分 + 动态开点 + 线段树合并)线段树合并模板离线/在线详解

    题目链接:雨天的尾巴 本题本身是一个非常简单的一道树上差分的模板题,但是由于变态的数据范围,我们直接用数组是存不下的(本来使用一颗普通的线段树直接维护最大值即可.但是本题的空间只有128MB,直接按照 ...

  6. 雨中的尾巴(线段树合并+树上差分)

    哇这道题 恶心死我 首先要知道,树上差分一般解决的问题是关于树上的覆盖问题 然后遇到覆盖问题尽量不要打树剖(会慢很多) 关于此题 因为这道题覆盖的是 从xxx到yyy的点 所以我们在 x,yx,yx, ...

  7. 【NOIP2016】【桶/线段树合并】【树上差分】天天爱跑步

    [题目描述] [思路] 这是道好题呀.考虑把一条路径(u,v)拆成两条:从u到lca(u,v),从lca(u,v)到v.下面我们以向上的路径为例讨论做法.对于一条向上的路径,它对一个点x有贡献当且仅当 ...

  8. 线段树合并与分裂维护树上最长上升子序列 + 点分治删点 ---- 2021 牛客多校第一场 C - Cut the tree(详解)

    题目大意: 给你一个树,树上每个点都有一个权值valnodeval_{node}valnode​,路径(u,v)(u,v)(u,v) 上所有点按顺序有序序列,令f(u,v)f(u,v)f(u,v)是这 ...

  9. 【CF700E】Cool Slogans【后缀自动机】【可持久化线段树合并】【树上倍增】

    传送门 题意:给定字符串SSS,求一堆字符串s1,s2,s3,...,sks_1,s_2,s_3,...,s_ks1​,s2​,s3​,...,sk​,满足s1s_1s1​是SSS的子串,且sis_i ...

  10. BZOJ4771 七彩树(dfs序+树上差分+主席树)

    考虑没有深度限制怎么做.显然的做法是直接转成dfs序上主席树,但如果拓展到二维变成矩形数颜色数肯定没法做到一个log. 另一种做法是利用树上差分.对于同种颜色的点,在每个点处+1,dfs序相邻点的lc ...

最新文章

  1. 强化学习教父Richard Sutton新论文探索决策智能体的通用模型:寻找跨学科共性...
  2. 用js获取当前地理位置的经纬度
  3. caffe filter type:Xavier
  4. 深入理解Spark 2.1 Core (五):Standalone模式运行的原理与源码分析
  5. SAP Knowledge Article TREX search determination
  6. cannot import name 'imresize' from 'scipy.misc'
  7. 《零基础看得懂的C语言入门教程 》——(三)轻轻松松理解第一个C语言程序
  8. java实用教程——组件及事件处理——DocumentEvent事件
  9. 牛客网【每日一题】4月2日 月月查华华的手机
  10. 关于phpcmsv9更新缓存出现链接被重置的问题
  11. C++ 多继承 初步01
  12. 企业数字化劳动力-Srise RPA产品
  13. [设计模式-结构型]桥接(Bridge )
  14. 对于java引用的总结
  15. tensorflow使用object detection实现目标检测超详细全流程(视频+图像集检测)
  16. Windows 环境下分布式跨域Session共享(转)
  17. 怎样找回W ndows7密钥,怎么找到windows7密钥
  18. Cisco Packet Tracer交换机划分VLAN
  19. 巨星传奇更新招股书:业务绑定歌手周杰伦 上半年营收降24%
  20. springcloud之Eureka高可用和用户认证

热门文章

  1. Java到底如何更优雅的处理空值?
  2. Nginx核心原理揭秘:Nginx为什么高效?
  3. 不懂开发的运维,未来该如何发展?
  4. 创业被泼冷水怎么办?
  5. oracle sql语句_7个维度查看oracle执行计划的sql语句执行效率
  6. 2019牛客多校第四场 A meeting
  7. 第二次公共考试,判断错题集
  8. 关于正则表达式中^和$
  9. background部分总结
  10. USACO Section 1.3 Prime Cryptarithm 解题报告