传送门

woc这该死的码农题……

把每一条边转化为它连接的两点中深度较深的那一个,然后就可以用树剖+线段树对路径进行修改了

然后顺便注意在上面这种转化之后,树剖的时候不能搞$LCA$

然后是几个注意点

1.线段树记两个标记,一个区间覆盖,一个区间加和

2.区间覆盖的标记更新后要把区间加和的标记删除,因为覆盖后之前的加和相当于都废了

3.因为上面那个原因,pushdown的时候先下传区间覆盖标记再下传区间加和标记

4.标记更新的时候记得把答案也一起更新

5.数组开大一点!!!

 //minamoto
#include<bits/stdc++.h>
using namespace std;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=2e5+;
int head[N],Next[N<<],ver[N<<],edge[N<<],tot=;
inline void add_edge(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
}
int dfn[N],sz[N],son[N],fa[N],dep[N],num[N],top[N],val[N],cnt,n;
void dfs1(int u){
sz[u]=,dep[u]=dep[fa[u]]+;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa[u]){
fa[v]=u,num[i>>]=v,dfs1(v),sz[u]+=sz[v];
if(sz[son[u]]<sz[v]) son[u]=v;
}
}
}
void dfs2(int u,int t){
dfn[u]=++cnt,top[u]=t;
if(son[u]){
dfs2(son[u],t);
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
}
int mx[N<<],all[N<<],add[N<<];
#define ls (p<<1)
#define rs (p<<1|1)
inline void upd(int p){mx[p]=max(mx[ls],mx[rs]);}
inline void pd(int p){
if(~all[p]){
all[ls]=all[rs]=mx[ls]=mx[rs]=all[p];
add[ls]=add[rs]=;
all[p]=-;
}
if(add[p]){
add[ls]+=add[p],add[rs]+=add[p];
mx[ls]+=add[p],mx[rs]+=add[p];
add[p]=;
}
}
void build(int p,int l,int r){
all[p]=-,add[p]=;
if(l==r) return (void)(mx[p]=val[l]);
int mid=(l+r)>>;
build(ls,l,mid),build(rs,mid+,r);
upd(p);
}
void change(int p,int l,int r,int x){
if(l==r) return (void)(mx[p]=val[l]);
int mid=(l+r)>>;pd(p);
x<=mid?change(ls,l,mid,x):change(rs,mid+,r,x);
upd(p);
}
void update(int p,int l,int r,int ql,int qr,int x){
if(ql<=l&&qr>=r) return (void)(all[p]=x,add[p]=,mx[p]=x);
int mid=(l+r)>>;pd(p);
if(ql<=mid) update(ls,l,mid,ql,qr,x);
if(qr>mid) update(rs,mid+,r,ql,qr,x);
upd(p);
}
void ADD(int p,int l,int r,int ql,int qr,int x){
if(ql<=l&&qr>=r) return (void)(add[p]+=x,mx[p]+=x);
int mid=(l+r)>>;pd(p);
if(ql<=mid) ADD(ls,l,mid,ql,qr,x);
if(qr>mid) ADD(rs,mid+,r,ql,qr,x);
upd(p);
}
int query(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return mx[p];
int mid=(l+r)>>,res=;pd(p);
if(ql<=mid) cmax(res,query(ls,l,mid,ql,qr));
if(qr>mid) cmax(res,query(rs,mid+,r,ql,qr));
return res;
}
inline void Change(int k,int x){
val[dfn[num[k]]]=x,change(,,n,dfn[num[k]]);
}
void Cover(int u,int v,int x){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(,,n,dfn[top[u]],dfn[u],x);
u=fa[top[u]];
}
if(u==v) return;
if(dep[u]<dep[v]) swap(u,v);
update(,,n,dfn[son[v]],dfn[u],x);
}
void Add(int u,int v,int x){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ADD(,,n,dfn[top[u]],dfn[u],x);
u=fa[top[u]];
}
if(u==v) return;
if(dep[u]<dep[v]) swap(u,v);
ADD(,,n,dfn[son[v]],dfn[u],x);
}
int get(int u,int v){
int res=;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
cmax(res,query(,,n,dfn[top[u]],dfn[u]));
u=fa[top[u]];
}
if(u==v) return res;
if(dep[u]<dep[v]) swap(u,v);
cmax(res,query(,,n,dfn[son[v]],dfn[u]));
return res;
}
int main(){
// freopen("testdata.in","r",stdin);
n=read();
for(int i=,u,v,e;i<n;++i)
u=read(),v=read(),e=read(),add_edge(u,v,e),add_edge(v,u,e);
dfs1(),dfs2(,);
for(int i=;i<n;++i) val[dfn[num[i]]]=edge[i<<];
build(,,n);
char s[];int u,v,x;
while(true){
scanf("%s",s+);if(s[]=='S') break;
switch(s[]){
case 'h':u=read(),x=read(),Change(u,x);break;
case 'o':u=read(),v=read(),x=read(),Cover(u,v,x);break;
case 'd':u=read(),v=read(),x=read(),Add(u,v,x);break;
case 'a':u=read(),v=read(),print(get(u,v));break;
}
}
Ot();
return ;
}

洛谷P4315 月下“毛景树”(树剖+线段树)的更多相关文章

  1. 洛谷P4315 月下“毛景树”

    题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...

  2. [洛谷P4315] 月下”毛景“树

    题目链接: 点我 题目分析: 树剖.将边权下放到下方点上(为什么要选深度更深的点?一个父亲可能对应多个儿子,但一个儿子只有一个父亲,即可以保证每个点只保存一条边权)成为经典点权+树剖裸题 注意链计算时 ...

  3. P4315 月下“毛景树”

    P4315 月下"毛景树" 题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬 ...

  4. P4315 月下“毛景树”(树链剖分)

    P4315 月下"毛景树"(树链剖分) 题面 简述: 边权转点权(在dfs1处转换) 把一条边权赋值在深度更深的上 需要实现对单边权的染色 , 路径边权的染色 , 路径边权的增加 ...

  5. P4315 月下“毛景树” (树链剖分+边剖分+区间覆盖+区间加+区间最大值)

    题目链接:https://www.luogu.org/problem/P4315 题目大意: 有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的.但是这棵“毛景树”有着神奇的魔力 ...

  6. P4315 月下“毛景树”[树剖]

    题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...

  7. 「洛谷4197」「BZOJ3545」peak【线段树合并】

    题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...

  8. 「洛谷3870」「TJOI2009」开关【线段树】

    题目链接 [洛谷] 题解 来做一下水题来掩饰ZJOI2019考炸的心情QwQ. 很明显可以线段树. 维护两个值,\(Lazy\)懒标记表示当前区间是否需要翻转,\(s\)表示区间还有多少灯是亮着的. ...

  9. 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)

    题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...

随机推荐

  1. Unique Binary Search Trees(dp)

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  2. POJ 2502 【思维是朴素的最短路 卡输入和建图】

    题意: 给出两个坐标,分别是小明家和小明学校的坐标. 给出多条地铁线,给出每站的坐标,已知地铁是双向的,每条线以-1 -1结尾. 给出地铁速度,步行速度. 地铁线可看成是顺次连接的线段. 求小明从家到 ...

  3. java面向对象基础编程题

    第一题: 设计一个形状类Shape,方法:求周长和求面积.形状类的子类:Rect(矩形),Circle(圆形).Rect类的子类:Square(正方形).不同的子类会有不同的计算周长和面积的方法1.总 ...

  4. Java多线程分析案例

    1. 多线程的创建方式 (1).继承 Thread类:但Thread本质上也是实现了Runnable 接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过 Thread 类的 sta ...

  5. AFNetworking配合Swift3.0请求数据

    首先用桥接或pods将AFNetworking导入项目,在这不再赘述,然后创建一个单例NetWorkTools.swift 继承:AFHTTPSessionManager import UIKit i ...

  6. php验证邮箱

    <?php if(isset($_POST['email'])){ $email = $_POST['email']; if(filter_var($email, FILTER_VALIDATE ...

  7. JMeter 系列之—-01使用

    用Jmeter 做压测,总体与LoadRunner 类似: 一.线程组 1. 线程数 2. 循环次数 单个线程循环次数 3. Ramp-up Period(in seconds) [1]决定多长时间启 ...

  8. LoadRunner关联需要转义的常见字符

    转义字符总结 在做手动关联时,取边界值的时候,会经常用到转义字符,现将转义字符整理如下: \b 退格             \f 换页             \n 换行             \ ...

  9. 一起talk C栗子吧(第一百二十一回:C语言实例--线程知识体系图)

    各位看官们.大家好,上一回中咱们说的线程属性的样例.这一回咱们说的样例是:线程知识体系图.闲话休提.言归正转. 让我们一起talk C栗子吧! 我们在前面的章回中介绍了与线程相关的知识,在今天的章回中 ...

  10. 浅谈JavaScript的字符串的replace方法

    JavaScript字符串提供了一个replace方法.replace方法可以接受两个参数:第一个参数可以使RegExp对象或者一个字符串,第二个参数可以是一个字符串或者一个函数.如果第一个参数是字符 ...