问题描述

LG4556


题解

对于每一个结点,建立一棵动态开点线段树。

然后自低向上合并线段树。

同时维护整个值域的最大值和最大值位置。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std; template <typename Tp>
void read(Tp &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
if(ch=='-') ch=getchar(),fh=-1;
else fh=1;
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
x*=fh;
} const int maxn=1000007;
const int maxm=2000007; int n,m;
int Head[maxn],Next[maxm],to[maxm],tot; int size[maxn],fa[maxn],son[maxn];
int dep[maxn],top[maxn],du[maxn]; void add(int x,int y){
to[++tot]=y,Next[tot]=Head[x],Head[x]=tot;
} void dfs1(int x,int f,int dp){
size[x]=1,fa[x]=f,dep[x]=dp;
int mx=-1;
for(int i=Head[x];i;i=Next[i]){
int y=to[i];
if(y==f) continue;
dfs1(y,x,dp+1);size[x]+=size[y];
if(size[y]>mx) mx=size[y],son[x]=y;
++du[x];
}
} void dfs2(int x,int tp){
top[x]=tp;
if(!son[x]) return;
dfs2(son[x],tp);
for(int i=Head[x];i;i=Next[i]){
int y=to[i];
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
} int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
return x;
} int L[maxn*22],R[maxn*22];
int rt[maxn],val[maxn*22],pos[maxn*22];
int cnt; void pushup(int x){
val[x]=max(val[L[x]],val[R[x]]);
if(val[x]<=0) return;
if(val[x]==val[L[x]]) pos[x]=pos[L[x]];
else pos[x]=pos[R[x]];
} int insert(int x,int l,int r,int p,int v){
if(!x) x=++cnt;
if(l==r){
val[x]+=v,pos[x]=l;
return x;
}
int mid=(l+r)>>1;
if(p<=mid) L[x]=insert(L[x],l,mid,p,v);
else R[x]=insert(R[x],mid+1,r,p,v);
pushup(x);
return x;
} int ans[maxn]; int merge(int p,int q,int l,int r){
if(!p||!q) return p+q;
if(l==r){
val[q]+=val[p],pos[q]=l;
return q;
}
int mid=(l+r)>>1;
L[q]=merge(L[p],L[q],l,mid);
R[q]=merge(R[p],R[q],mid+1,r);
pushup(q);
return q;
} int main(){
read(n);read(m);
for(int i=1,x,y;i<n;i++){
read(x);read(y);
add(x,y);add(y,x);
}
dfs1(1,0,1);dfs2(1,1);
for(int i=1;i<=n;i++) rt[i]=++cnt;
for(int i=1,x,y,z;i<=m;i++){
read(x);read(y);read(z);
int LCA=lca(x,y);
insert(rt[x],1,100000,z,1);
insert(rt[y],1,100000,z,1);
insert(rt[LCA],1,100000,z,-1);
insert(rt[fa[LCA]],1,100000,z,-1);
}
queue<int>q;
for(int i=1;i<=n;i++){
if(!du[i]) q.push(i);
}
while(!q.empty()){
int x=q.front();q.pop();
ans[x]=pos[rt[x]];
merge(rt[x],rt[fa[x]],1,100000);
--du[fa[x]];
if(!du[fa[x]]) q.push(fa[x]);
}
for(int i=1;i<=n;i++){
printf("%d\n",ans[i]);
}
return 0;
}

LG4556 [Vani有约会]雨天的尾巴 动态开点线段树+线段树合并的更多相关文章

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

    [Vani有约会]雨天的尾巴 LG传送门 线段树合并入门好题. 先别急着上线段树合并,考虑一下这题的暴力.一看就是树上差分,对于每一个节点统计每种救济粮的数量,再一遍dfs把差分的结果统计成答案.如果 ...

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

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

  3. 洛谷 P4556 [Vani有约会]雨天的尾巴 解题报告

    P4556 [Vani有约会]雨天的尾巴 题目背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒 ...

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

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

  5. 「Luogu4556」Vani有约会-雨天的尾巴

    「Luogu4556」Vani有约会-雨天的尾巴 传送门 很显然可以考虑树上差分+桶,每次更新一条链就是把这条链上的点在桶对应位置打上 \(1\) 的标记, 最后对每个点取桶中非零值的位置作为答案即可 ...

  6. [题解] P4556 [Vani有约会]雨天的尾巴

    [题解] P4556 [Vani有约会]雨天的尾巴 ·题目大意 给定一棵树,有m次修改操作,每次修改 \(( x\) \(y\) \(z )\) 表示 \((x,y)\) 之间的路径上数值 \(z\) ...

  7. [Vani有约会]雨天的尾巴——树上差分+动态开点线段树合并

    题目描述 首先村落里的一共有n座房屋,并形成一个树状结构.然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋z类型的救济粮. 然后深绘里想知道,当所 ...

  8. P4556 [Vani有约会]雨天的尾巴

    目录 思路 优化 过程中的问题/疑问 错误 代码 思路 每个节点维护一课线段树(当然是动态开点) 线段树的作用是统计这个节点有多少种粮食型号,以及最多的粮食型号 然后树上差分,u和v点 +1,lca( ...

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

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

随机推荐

  1. JMeter基础知识系列三

    JMeter测试结果字段的意义: Label:定义HTTP请求名称. Samples:表示这次测试中一共发出了多少个请求. Average:平均响应时长,当使用了Transaction Control ...

  2. 用CSS绘制实体三角形

    用CSS绘制实体三角形 使用CSS盒模型中的border(边框)即可实现如下所示的三角形: .box { width: 0; height: 0; border-width: 100px; borde ...

  3. bzoj3293 分金币

    题目链接 problem 圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使 得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值. so ...

  4. JWT的优点和实现Token认证的安全问题

    JWT的优点和实现Token认证的安全问题 一.什么是JWT JWT——Json web token  是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,可实现无状态.分布式的Web应 ...

  5. PHP递归函数return返回null的问题

    前段时间在写递归函数的时候碰到个问题,返回值一直为null,这里记录一下. 写个小例子: /** * @param $i * @return mixed */ function recursion($ ...

  6. js forEach参数详解,forEach与for循环区别,forEach中如何删除数组元素

     壹 ❀ 引 在JS开发工作中,遍历数组的操作可谓十分常见了,那么像for循环,forEach此类方法自然也不会陌生,我个人也觉得forEach不值得写一篇博客记录,直到我遇到了一个有趣的问题,我们来 ...

  7. 05-Django模型(2)

    1.特殊查询 F和Q查询: 之前的查询都是模型对象的属性与常量值比较,两个属性怎么比较呢?使用F查询. F查询语法: from django.db.models import F F('属性名称') ...

  8. PVANET: Deep but Lightweight Neural Networks for Real-time Object Detection

    URL: https://arxiv.org/abs/1608.08021 year: 2016 TL;DR PVANet 一个轻量级多物体目标检测架构, 遵循 "less channels ...

  9. Mac下如何复制webp图片

      将 WebP 格式图片拖到 Chrome 浏览器标签栏中(浏览器是肯定支持查看的,而且是 Google 自家的),这个时候图片是能够正常查看的.我们右键选中图片,选择「复制图片」. 打开 macO ...

  10. 愉快地使用Groovy Shell

    这是一篇有关Groovy Shell的帖子,以及它如何在日常工作中为您提供帮助(只要您是软件开发人员).无论您使用哪种编程语言或技术,都可以从Groovy Shell中受益.唯一真正的要求是您能够编写 ...