题目链接:https://www.luogu.org/problem/P4315

题目大意:

有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的。但是这棵“毛景树”有着神奇的魔力,他能改变树枝上毛毛果的个数:
Change k w:将第k条树枝上毛毛果的个数改变为w个。
Cover u v w:将节点u与节点v之间的树枝上毛毛果的个数都改变为w个。
Add u v w:将节点u与节点v之间的树枝上毛毛果的个数都增加w个。 由于毛毛虫很贪,于是他会有如下询问:
Max u v:询问节点u与节点v之间树枝上毛毛果个数最多有多少个。

解题思路:一道边权树剖题,代码很长,调试起来还是有点复杂。

注意一下几点:

1.可以把边权转化为点权,因为每一个孩子节点通向父节点的边是唯一的,所以可以将每个边的边权转到边所连的孩子节点上(可在树剖的第一个dfs中完成)

2.修改一条链上的权值时,要注意链两端的点的lca不能够被修改,因为lca所对应的边权不在这一条链上。

3.Change 操作是修改第k条树枝,k为读入的顺序,而树的存边是双向的,所以要将读入的k乘以二在进行后面的操作。

4.下推标记的时候如果有覆盖标记不要忘了清除加的标记

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=;
int tot,cnt,head[maxn],n,m,v[maxn];
ll tree[maxn*],lazy[maxn*],cov[maxn*];
int d[maxn],size[maxn],son[maxn],id[maxn],rk[maxn],fa[maxn],top[maxn];
//cov为覆盖标记,lazy为累加标记
struct Edge{
int u,v,w,next;
}edge[maxn<<];
void add(int u,int v,int w){
edge[++tot].v=v;
edge[tot].u=u;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot;
}
void dfs1(int u,int pre){
d[u]=d[pre]+;
fa[u]=pre;
size[u]=;
for(int i=head[u];i!=-;i=edge[i].next){
int vv=edge[i].v;
if(vv!=pre){
dfs1(vv,u);
size[u]+=size[vv];
v[vv]=edge[i].w; //边权转为点权
if(size[son[u]]<size[vv]) son[u]=vv;
}
}
}
void dfs2(int u,int tp){
top[u]=tp,id[u]=++cnt,rk[cnt]=u;
if(son[u]) dfs2(son[u],tp);
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
void pushup(int rt){
tree[rt]=max(tree[rt<<],tree[rt<<|]);
}
void pushdown(int l,int r,int rt){
if(cov[rt]!=-){
cov[rt<<]=cov[rt<<|]=cov[rt];
tree[rt<<]=tree[rt<<|]=cov[rt];
lazy[rt<<]=lazy[rt<<|]=; //将孩子节点的lazy标记清0
cov[rt]=-;
}
if(lazy[rt]){
tree[rt<<]=tree[rt<<]+lazy[rt];
tree[rt<<|]=tree[rt<<|]+lazy[rt];
lazy[rt<<]+=lazy[rt];
lazy[rt<<|]+=lazy[rt];
lazy[rt]=;
}
}
void build(int l,int r,int rt){
lazy[rt]=;
cov[rt]=-;
if(l==r){
tree[rt]=v[rk[l]];
return;
}
int mid=l+r>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
pushup(rt);
}
void update1(int L,int R,int val,int l,int r,int rt){ //区间Cover和Change
if(L<=l&&R>=r){
tree[rt]=val;
cov[rt]=val;
lazy[rt]=; //将lazy标记清0
return;
}
int mid=l+r>>;
pushdown(mid-l+,r-mid,rt);
if(mid>=L) update1(L,R,val,l,mid,rt<<);
if(mid<R) update1(L,R,val,mid+,r,rt<<|);
pushup(rt);
}
void update2(int L,int R,int val,int l,int r,int rt){ //区间Add
if(L<=l&&R>=r){
tree[rt]+=val;
lazy[rt]+=val;
return;
}
int mid=l+r>>;
pushdown(mid-l+,r-mid,rt);
if(mid>=L) update2(L,R,val,l,mid,rt<<);
if(mid<R) update2(L,R,val,mid+,r,rt<<|);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt){ //区间求Max
if(L<=l&&R>=r) return tree[rt];
int mid=l+r>>; ll res=;
pushdown(mid-l+,r-mid,rt);
if(mid>=L) res=max(res,query(L,R,l,mid,rt<<));
if(mid<R) res=max(res,query(L,R,mid+,r,rt<<|));
return res;
}
void updates1(int x,int y,int val){ //Cover
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]]) swap(x,y);
update1(id[top[x]],id[x],val,,n,);
x=fa[top[x]];
}
if(id[x]>id[y]) swap(x,y);
update1(id[x]+,id[y],val,,n,); //不能更新lca所以是id[x]+1
}
void updates2(int x,int y,int val){ //Add
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]]) swap(x,y);
update2(id[top[x]],id[x],val,,n,);
x=fa[top[x]];
}
if(id[x]>id[y]) swap(x,y);
update2(id[x]+,id[y],val,,n,); //不能更新lca所以是id[x]+1
}
ll ask(int x,int y){ //求Max
ll res=;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]]) swap(x,y);
res=max(res,query(id[top[x]],id[x],,n,));
x=fa[top[x]];
}
if(id[x]>id[y]) swap(x,y);
res=max(res,query(id[x]+,id[y],,n,));
return res;
}
int main(){
scanf("%d",&n);
memset(head,-,sizeof(head));
cnt=,tot=;
for(int i=;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w); add(v,u,w);
}
dfs1(,),dfs2(,);
build(,n,);
while(true){
char op[];
int x,l,r,rt,val;
scanf("%s",op);
if(op[]=='t') break;
if(op[]=='h'){
scanf("%d%d",&x,&val); //因为是无向边,所以x*2表示的就是第x条边
x=d[edge[x*].u]>d[edge[x*].v]?edge[x*].u:edge[x*].v;
update1(id[x],id[x],val,,n,); //Change操作
} else if(op[]=='o'){
scanf("%d%d%d",&l,&r,&val);
updates1(l,r,val); //Cover操作
} else if(op[]=='d'){
scanf("%d%d%d",&l,&r,&val);
updates2(l,r,val); //Add操作
} else if(op[]=='a'){
scanf("%d%d",&l,&r);
printf("%lld\n",ask(l,r)); //Max操作
}
}
return ;
}

P4315 月下“毛景树” (树链剖分+边剖分+区间覆盖+区间加+区间最大值)的更多相关文章

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

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

  2. P4315 月下“毛景树”

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

  3. 洛谷P4315 月下“毛景树”(树剖+线段树)

    传送门 woc这该死的码农题…… 把每一条边转化为它连接的两点中深度较深的那一个,然后就可以用树剖+线段树对路径进行修改了 然后顺便注意在上面这种转化之后,树剖的时候不能搞$LCA$ 然后是几个注意点 ...

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

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

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

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

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

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

  7. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  8. 【BZOJ-1984】月下“毛景树” 树链剖分

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1314  Solved: 416[Submit][Status][Discu ...

  9. Bzoj 1984: 月下“毛景树” 树链剖分

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1282  Solved: 410[Submit][Status][Discu ...

随机推荐

  1. 对AC自动机+DP题的一些汇总与一丝总结 (1)

    (1)题意 : 输入n.m.k意思就是给你 m 个模式串,问你构建长度为 n 至少包含 k 个模式串的方案有多少种 分析:(HDU2825) DP[i][j][k] 表示 DP[第几步][哪个节点结尾 ...

  2. vundle就是vim bundle的插件管理成ide

    如何配置一个高效的php编辑环境, 很好 对vundle的操作, 除了仓库名称是vundle.git (*.git就是仓库) 和 本地目录名是 vundle之外, 其他的操作都是bundle git ...

  3. 安装 Windows 系统在 NVMe 规范的 M.2 接口的固态硬盘(SSD)上

    作为一个程序员很重要的一项技能就是装系统 @_@,以前我都是随便用网上的工具做个系统盘,每次要用直接随手就搞好了,节省大家时间. 但最近同事装了个贼小的固态,然后我启动盘里的系统果断识别不出来他的固态 ...

  4. JS - defer 和 async

    普通 <script src="script.js"></script> 没有 defer 或 async,浏览器会立即加载并执行指定的脚本,"立 ...

  5. 简要介绍一下MD5加密的书写

    大家应该多清楚数据的重要性,可以假设一下:一个非常大的企业,因为一个程序员的疏忽大意,没有使用MD5加密,那么可以说这个企业的数据库是非常不安全的,可以轻而易举的的访问你的数据库,并执行任何操作. 下 ...

  6. Spring中通过变量和import标签来控制加载哪些bean

    需求:根据设置变量,来加载某个spring的bean的配置文件,这个配置文件中,有某些使用的bean.在一些情况下,不希望这些bean被初始化和加载进context中,也不需要被外面访问到. 在spr ...

  7. Hibernate API的使用(Query、Criteria、SQLQuery对象)

    Query对象 我们使用Query对象不需要编写SQL语句,但是得写HQL语句. HQL:Hibernate Query Language:Hibernate提供的查询语言,和SQL语句很相似. HQ ...

  8. .net通用签名方法 webapi签名方法

    验证签名方法 [HttpGet] public HttpResponseMessage LockRegister(string 参数1, int 参数2, string 参数3, string 参数4 ...

  9. Snow的追寻--线段树维护树的直径

    Snow终于得知母亲是谁,他现在要出发寻找母亲.王国中的路由于某种特殊原因,成为了一棵有n个节点的根节点为1的树,但由于"Birds are everywhere.",他得到了种种 ...

  10. Fabric CA/数字证书管理

    MSP(Membership Service Provider)成员管理服务提供商 名词: 1.CSR(Cerificate Signing Request):证书签署请求文件 CSR里包含申请者的 ...