[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][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有约会]雨天的尾巴(树上差分+线段树合并)相关推荐
- 洛谷 - P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并(树上差分+线段树合并)
题目链接:点击查看 题目大意:给出一棵树,再给出 m 次操作,每次操作会选择两个点 ( x , y ) ,使得这条路径上的所有点的种类 z 加一,最后问每个点的哪个种类出现的频率最高,若多个种类出现频 ...
- [Vani有约会]雨天的尾巴 (线段树合并)
题目链接 Solution 树上差分+线段树合并. 在每个节点上维护一棵权值线段树. 然后如果需要修改 \(x,y\) 两点,则在 \(x\) 处和 \(y\) 处分别加上 \(1\) 的权值. 然后 ...
- 线段树分裂与合并 ---- 树上差分 P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并
题目链接 解题思路: 首先题目是对u,vu,vu,v这两条路径上面添加一个zzz,然后运用树上点的差分思想,对于分发路径u,vu,vu,v,我们在uuu上+1+1+1,在vvv上+1+1+1,在lca ...
- 洛咕 P4556 [Vani有约会]雨天的尾巴
终于把考试题清完了...又复活了... 树上差分,合并用线段树合并,但是空间会炸. 某大佬:lca和fa[lca]减得时候一定已经存在这个节点了,所以放进vector里,合并完之后减掉就好了... 玄 ...
- 【线段树合并】解题报告:luogu P4556雨天的尾巴 (树上对点差分 + 动态开点 + 线段树合并)线段树合并模板离线/在线详解
题目链接:雨天的尾巴 本题本身是一个非常简单的一道树上差分的模板题,但是由于变态的数据范围,我们直接用数组是存不下的(本来使用一颗普通的线段树直接维护最大值即可.但是本题的空间只有128MB,直接按照 ...
- 雨中的尾巴(线段树合并+树上差分)
哇这道题 恶心死我 首先要知道,树上差分一般解决的问题是关于树上的覆盖问题 然后遇到覆盖问题尽量不要打树剖(会慢很多) 关于此题 因为这道题覆盖的是 从xxx到yyy的点 所以我们在 x,yx,yx, ...
- 【NOIP2016】【桶/线段树合并】【树上差分】天天爱跑步
[题目描述] [思路] 这是道好题呀.考虑把一条路径(u,v)拆成两条:从u到lca(u,v),从lca(u,v)到v.下面我们以向上的路径为例讨论做法.对于一条向上的路径,它对一个点x有贡献当且仅当 ...
- 线段树合并与分裂维护树上最长上升子序列 + 点分治删点 ---- 2021 牛客多校第一场 C - Cut the tree(详解)
题目大意: 给你一个树,树上每个点都有一个权值valnodeval_{node}valnode,路径(u,v)(u,v)(u,v) 上所有点按顺序有序序列,令f(u,v)f(u,v)f(u,v)是这 ...
- 【CF700E】Cool Slogans【后缀自动机】【可持久化线段树合并】【树上倍增】
传送门 题意:给定字符串SSS,求一堆字符串s1,s2,s3,...,sks_1,s_2,s_3,...,s_ks1,s2,s3,...,sk,满足s1s_1s1是SSS的子串,且sis_i ...
- BZOJ4771 七彩树(dfs序+树上差分+主席树)
考虑没有深度限制怎么做.显然的做法是直接转成dfs序上主席树,但如果拓展到二维变成矩形数颜色数肯定没法做到一个log. 另一种做法是利用树上差分.对于同种颜色的点,在每个点处+1,dfs序相邻点的lc ...
最新文章
- 强化学习教父Richard Sutton新论文探索决策智能体的通用模型:寻找跨学科共性...
- 用js获取当前地理位置的经纬度
- caffe filter type:Xavier
- 深入理解Spark 2.1 Core (五):Standalone模式运行的原理与源码分析
- SAP Knowledge Article TREX search determination
- cannot import name 'imresize' from 'scipy.misc'
- 《零基础看得懂的C语言入门教程 》——(三)轻轻松松理解第一个C语言程序
- java实用教程——组件及事件处理——DocumentEvent事件
- 牛客网【每日一题】4月2日 月月查华华的手机
- 关于phpcmsv9更新缓存出现链接被重置的问题
- C++ 多继承 初步01
- 企业数字化劳动力-Srise RPA产品
- [设计模式-结构型]桥接(Bridge )
- 对于java引用的总结
- tensorflow使用object detection实现目标检测超详细全流程(视频+图像集检测)
- Windows 环境下分布式跨域Session共享(转)
- 怎样找回W ndows7密钥,怎么找到windows7密钥
- Cisco Packet Tracer交换机划分VLAN
- 巨星传奇更新招股书:业务绑定歌手周杰伦 上半年营收降24%
- springcloud之Eureka高可用和用户认证