传送门

这题真棒!

首先是这题是边权题,为了方便处理,化为点权。可一条边有两点点啊,用哪个存权值好呢?当然是儿子啦!因为一个儿子唯一对应一个连着父亲的边。

然后这题对于线段树涉及到区间最值查询、区间修改、区间加、单点修改,我很偷懒地把单点修改弄成区间修改了。

那么运算优先级问题:区间覆盖优于区间加,因为一旦有一个区间覆盖出现,之前所有的区间加都可以情空,处理起来很方便。

那么就是剖分的问题了:你会发现路径上的LCA存的值,是属于LCA和它父亲的边,一定不在这条路径上,所以不可以访问。最初考虑求出LCA,然后单点修改,区间操作,然后再单点修改。但是这样很麻烦啊……厚颜无耻地看了题解……你会发现我们在剖分的过程中,最后一定会跳到同一条重链上,深度小的就是LCA!!!那么我们可以怎么不去访问它呢?只需要把它的dfs序+1即可,因为这是一条重链,+1后就是它的重儿子!还可以保证区间不会断!

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 100005
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mid ((l+r)>>1)struct table {int v,w,next;
}G[MAXN<<1];struct edge {int u,v,w;
}E[MAXN];int head[MAXN];int dfn[MAXN],top[MAXN],val[MAXN];
int size[MAXN],son[MAXN],son_w[MAXN],d[MAXN],fa[MAXN];int seg[MAXN<<2],tag[MAXN<<2],sum[MAXN<<2];
int N,tot = 0,num = 0;inline void add(int u,int v,int w) {G[++tot].v = v;G[tot].w = w;G[tot].next = head[u];head[u] = tot;
}inline void pushup(int rt) {seg[rt] = std::max(seg[lson],seg[rson]);
}void Build(int rt,int l,int r) {tag[rt] = -1;sum[rt] = 0;if(l==r) {seg[rt] = val[l];return;}Build(lson,l,mid);Build(rson,mid+1,r);pushup(rt);
}inline void pushdown(int rt) {if(tag[rt]!=-1) {sum[lson] = sum[rson] = 0;tag[lson] = tag[rson] = seg[lson] = seg[rson] = tag[rt];tag[rt] = -1;}sum[lson] += sum[rt];sum[rson] += sum[rt];seg[lson] += sum[rt];seg[rson] += sum[rt];sum[rt] = 0;
}void sum_update(int C,int L,int R,int rt,int l,int r) {if(L<=l&&R>=r) {seg[rt] += C;sum[rt] += C;return;}if(L>r||R<l) return;pushdown(rt);if(L<=mid) sum_update(C,L,R,lson,l,mid);if(r>mid) sum_update(C,L,R,rson,mid+1,r);pushup(rt);
}void tag_update(int C,int L,int R,int rt,int l,int r) {if(L<=l&&R>=r) {seg[rt] = C;sum[rt] = 0;tag[rt] = C;return;}if(L>r||R<l) return;pushdown(rt);if(L<=mid) tag_update(C,L,R,lson,l,mid);if(r>mid) tag_update(C,L,R,rson,mid+1,r);pushup(rt);
}int query(int L,int R,int rt,int l,int r) {if(L<=l&&R>=r) return seg[rt];if(L>r||R<l) return 0;pushdown(rt);int maxx = 0;if(L<=mid) maxx = query(L,R,lson,l,mid);if(r>mid) maxx = std::max(maxx,query(L,R,rson,mid+1,r));pushup(rt);return maxx;
}void dfs1(int u,int father) {d[u] = d[father] + 1; size[u] = 1;son[u] = 0; son_w[u] = 0; fa[u] = father;for(int i=head[u];i;i=G[i].next) {int v = G[i].v; if(v==father) continue;dfs1(v,u); size[u] += size[v];if(size[son[u]]<size[v]) son[u] = v,son_w[u] = G[i].w;}
}void dfs2(int u,int tp,int w) {dfn[u] = ++num; val[num] = w; top[u] = tp;if(son[u]) dfs2(son[u],tp,son_w[u]);for(int i=head[u];i;i=G[i].next) {int v = G[i].v;if(v==fa[u]||v==son[u]) continue;dfs2(v,v,G[i].w);}
}inline void chain_sum_update(int u,int v,int w) {while(top[u]!=top[v]) {if(d[top[u]]<d[top[v]]) std::swap(u,v);sum_update(w,dfn[top[u]],dfn[u],1,1,N);u = fa[top[u]];}if(d[u]>d[v]) std::swap(u,v);sum_update(w,dfn[u]+1,dfn[v],1,1,N);
}inline void chain_tag_update(int u,int v,int w) {while(top[u]!=top[v]) {if(d[top[u]]<d[top[v]]) std::swap(u,v);tag_update(w,dfn[top[u]],dfn[u],1,1,N);u = fa[top[u]];}if(d[u]>d[v]) std::swap(u,v);tag_update(w,dfn[u]+1,dfn[v],1,1,N);
}inline int chain_query(int u,int v) {int maxx = 0;while(top[u]!=top[v]) {if(d[top[u]]<d[top[v]]) std::swap(u,v);maxx = std::max(maxx,query(dfn[top[u]],dfn[u],1,1,N));u = fa[top[u]];}if(d[u]>d[v]) std::swap(u,v);maxx = std::max(maxx,query(dfn[u]+1,dfn[v],1,1,N));return maxx;
}inline int get_opt() {char ch = getchar();int opt = 0;while(ch<'A'||ch>'Z') ch = getchar();if(ch=='M') opt = 1;else if(ch=='A') opt = 2;else if(ch=='C') {ch = getchar();if(ch=='h') opt = 3;else opt = 4;}else if(ch=='S') opt = 0;while(ch!=' '&&ch!='\n'&&ch!=EOF) ch = getchar();return opt;
}int main() {int u,v,w;scanf("%d",&N);for(int i=1;i<N;++i) {scanf("%d%d%d",&u,&v,&w);E[i] = (edge){u,v};add(u,v,w); add(v,u,w);}d[0] = size[0] = 0;dfs1(1,0); dfs2(1,0,0);Build(1,1,N);int opt;while((opt = get_opt())!=0) {if(opt==1) {scanf("%d%d",&u,&v);printf("%d\n",chain_query(u,v));}else if(opt==2) {scanf("%d%d%d",&u,&v,&w);chain_sum_update(u,v,w);}else if(opt==3) {scanf("%d%d",&u,&w);chain_tag_update(E[u].u,E[u].v,w);}else if(opt==4) {scanf("%d%d%d",&u,&v,&w);chain_tag_update(u,v,w);}}return 0;
}

转载于:https://www.cnblogs.com/Neworld2002/p/10016968.html

[luogu4315] 月下“毛景树”相关推荐

  1. 树剖+线段树||树链剖分||BZOJ1984||Luogu4315||月下“毛景树”

    题面:月下"毛景树" 题解:是道很裸的树剖,但处理的细节有点多(其实是自己线段树没学好).用一个Dfs把边权下移到点权,用E数组记录哪些边被用到了:前三个更新的操作都可以合并起来, ...

  2. [bzoj1984]月下“毛景树” 树链剖分

    1984: 月下"毛景树" Time Limit: 20 Sec  Memory Limit: 64 MB [Submit][Status][Discuss] Descriptio ...

  3. BZOJ1984: 月下“毛景树”

    BZOJ 1984: 月下"毛景树" Time Limit: 20 Sec  Memory Limit: 64 MB Submit: 1583  Solved: 500 [Subm ...

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

    题目链接: P4315 月下"毛景树" 大致题意 给定一棵由nnn个节点的树, 由n−1n - 1n−1带权边构成. 有如下444种操作: Change k c: 把第kkk条边的 ...

  5. 洛谷P4315 月下“毛景树” 题解

    洛谷P4315 月下"毛景树" 题解 题目链接:P4315 月下"毛景树" 题意:请维护一个数据结构,支持 改第 kkk 条边的边权 结点 uuu 到 vvv ...

  6. [BZOJ1984] 月下“毛景树”

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

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

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

  8. bzoj 1984: 月下“毛景树” 线段树+树链剖分

    题意 给出一棵n个节点的树,每条边都有权值,要求资瓷以下操作: Max x y表示查询x到y之间的最大权值 Cover x y z表示把x到y的权值赋为z Change x y表示把第x条边的权值变成 ...

  9. 【洛谷P4315】月下“毛景树”(树链剖分)

    这是一道毒瘤题. 首先题目中给的是边权而不是点权,但是我们把边权移到点上就行了 但是要注意,之后我们修改u,v两点之间的路径时,就不要修改他们的lca,以及当要修改单边的时候,把边的编号*2(因为是双 ...

  10. 洛谷 P4315 月下“毛景树”(边树剖)

    题目不算难,但是代码量需要控制 主要说一下线段树上的操作,因为有两个相关的区间操作标记,应该先覆盖后增加,因为覆盖操作会影响增加操作 const int N=1e5+5;int n,m;int i,j ...

最新文章

  1. ExtJS grid简单应用之 展示JSON数据
  2. NLP之WordCloud:基于jieba+matplotlib库对一段文本生成词云图~~情人节最好的礼物(给你一张过去的词云图,看看那时我们的爱情)
  3. 解析网络诊断利器SreCli-Net
  4. sqlite数据类型、关键词及创建、修改、删除数据表
  5. ArcGIS10.6中,在3D分析工具中创建视线之后,怎么将其删除?
  6. 销货清单数据_2020年8月数据科学阅读清单
  7. pc-bsd安装教程_桌面用户的BSD:PC-BSD的回顾
  8. 职责链模式在开发中的应用
  9. php git server,server.php
  10. java 序列化快捷键_IntelliJ IDEA生成 Serializable序列化UID的快捷键
  11. Hive基本操作入门
  12. 如何迅速的找到合适的开发者?
  13. 浅谈几种常见 RAID 的异同
  14. mysql sql语句执行到一半会怎么样?
  15. 【机器学习】主成分分析 (PCA)、无监督特征提取
  16. 趋势科技防毒墙网络版—OfficeScan
  17. 产品经理入门知识梳理(含思维导图
  18. 如何修复iTunes中未显示的iPhone或iPad
  19. 探索Bitmap使用姿势
  20. 根据出生年月日计算出生了多少年,多少月,多少天

热门文章

  1. MQ消息队列(一)什么是消息队列
  2. 高翔视觉slam十四讲习题(1)
  3. angr源码分析——数据依赖图 DDG
  4. vp230引脚功能_CAN收发器—TJA1040与TJA1050区别
  5. React Suspense 尝鲜,处理前后端IO异步操作
  6. CSS强制图像调整大小并保持纵横比
  7. 利用python批量查询企业信息_Python 实现批量查询域名可用性
  8. 新建 umi 项目,Error: Rendered more hooks 或者 Rendered fewer hooks
  9. 认识中药(5)--胖大海
  10. MFC 解压7z文件