洛谷P4315 月下“毛景树”(树剖+线段树)
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 月下“毛景树”(树剖+线段树)的更多相关文章
- 洛谷P4315 月下“毛景树”
题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...
- [洛谷P4315] 月下”毛景“树
题目链接: 点我 题目分析: 树剖.将边权下放到下方点上(为什么要选深度更深的点?一个父亲可能对应多个儿子,但一个儿子只有一个父亲,即可以保证每个点只保存一条边权)成为经典点权+树剖裸题 注意链计算时 ...
- P4315 月下“毛景树”
P4315 月下"毛景树" 题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬 ...
- P4315 月下“毛景树”(树链剖分)
P4315 月下"毛景树"(树链剖分) 题面 简述: 边权转点权(在dfs1处转换) 把一条边权赋值在深度更深的上 需要实现对单边权的染色 , 路径边权的染色 , 路径边权的增加 ...
- P4315 月下“毛景树” (树链剖分+边剖分+区间覆盖+区间加+区间最大值)
题目链接:https://www.luogu.org/problem/P4315 题目大意: 有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的.但是这棵“毛景树”有着神奇的魔力 ...
- P4315 月下“毛景树”[树剖]
题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...
- 「洛谷4197」「BZOJ3545」peak【线段树合并】
题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...
- 「洛谷3870」「TJOI2009」开关【线段树】
题目链接 [洛谷] 题解 来做一下水题来掩饰ZJOI2019考炸的心情QwQ. 很明显可以线段树. 维护两个值,\(Lazy\)懒标记表示当前区间是否需要翻转,\(s\)表示区间还有多少灯是亮着的. ...
- 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)
题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...
随机推荐
- oc温习二:基本运算及基本运算符
C语言一共有34种运算符,如下: 运算符分类: 1.按照功能划分: (1)算术运算符 + 加法运算符 - 减法运算符 或者负值运算符 * 乘法运算符 / 除法运算符 % 模运算符,或者取余运算符,要求 ...
- [bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树
游览计划 bzoj-2595 wc-2008 题目大意:题目链接.题目连接. 注释:略. 想法:裸题求斯坦纳树. 斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代 ...
- P1918 保龄球 洛谷
https://www.luogu.org/problem/show?pid=1918 题目描述 DL 算缘分算得很烦闷,所以常常到体育馆去打保龄球解闷.因为他保龄球已经打了几十年了,所以技术上不成问 ...
- codechef Taxi Driver
题意: 给N个点求任意两个点的“距离”总和: A,B的“距离”定义为:min(|ax-bx|,|ay-by|) (n<200000) 好题! 解析: 看着没思路 先是公式化简:让 ax=sx+s ...
- 2017icpc乌鲁木齐网络赛Colored Graph (构造)
题目 https://nanti.jisuanke.com/t/16958 题意 给定一个n(n<=500)个点的无向图,给每条边黑白染色,输出同色三角形最少的个数和对应的方案 分析 首先考虑给 ...
- 简单使用SOCKET,TCP,UDP模式之间的通信
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机网络OSI模型中, ...
- Java数组操作方法收集(快速判断某个值在这个数组中)
Java数组操作最高效的方式是循环取值,如果转换成集合那么就会分配内存,效率不如前者,但是方法多,需要在性能调优上去权衡.切记:数组是数组,集合是集合. 下面是收集最常用的数组转成集合的操作方法: i ...
- eclipse提速02 - eclipse.ini优化
给eclipse执行jvm.它可以让你使用自己的jdk,而不是系统环境变量所指定的jdk -vm /path/to/your/java 使用最新的jdk来运行eclipse.使用最新的jdk要好很多. ...
- java获取本机机器名
java获取本机机器名 InetAddress.getLocalHost().getHostName().toString();
- Linux中断处理驱动程序编写
本章节我们一起来探讨一下Linux中的中断 中断与定时器:中断的概念:指CPU在执行过程中,出现某些突发事件急待处理,CPU暂停执行当前程序,转去处理突发事件,处理完后CPU又返回原程序被中断的位置继 ...