Description

毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。爬啊爬~爬啊爬~~ 毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果~~~ “毛景树”上有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之间树枝上毛毛果个数最多有多少个。
Input

第一行一个正整数N。 接下来N-1行,每行三个正整数Ui,Vi和Wi,第i+1行描述第i条树枝。表示第i条树枝连接节点Ui和节点Vi,树枝上有Wi个毛毛果。 接下来是操作和询问,以“Stop”结束。
Output

对于毛毛虫的每个询问操作,输出一个答案。
Sample Input

4

1 2 8

1 3 7

3 4 9

Max 2 4

Cover 2 4 5

Add 1 4 10

Change 1 16

Max 2 4

Stop

Sample Output

9

16

【Data Range】

1<=N<=100,000,操作+询问数目不超过100,000。

保证在任意时刻,所有树枝上毛毛果的个数都不会超过10^9个。

HINT

Source

树的分治


bzoj不让我交!!!

我和【submit】这个键战斗了无数次!!

然后每次都【无法显示该网页】!!

挖坑!!!

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;const int SZ = 400010;
const int INF = 1000000010;int head[SZ],nxt[SZ],tot = 0,to[SZ];void build_edge(int f,int t)
{to[++ tot] = t;nxt[tot] = head[f];head[f] = tot;
}int top[SZ],deep[SZ],sz[SZ],son[SZ],fa[SZ],inseg[SZ];void dfs_1(int u,int f)
{fa[u] = f;sz[u] = 1;deep[u] = deep[f] + 1;for(int i = head[u];i;i = nxt[i]){int v = to[i];if(v == f) continue;dfs_1(v,u);sz[u] += sz[v];if(!son[u] || sz[son[u]] < sz[v]) son[u] = v;}
}int totp = 0;void dfs_2(int u,int tp)
{inseg[u] = ++ totp;top[u] = tp;if(!son[u])  return;dfs_2(son[u],tp);for(int i = head[u];i;i = nxt[i]){int v = to[i];if(v == fa[u] || v == son[u]) continue;dfs_2(v,v);}
}struct segment{int l,r;int add,maxn,c;
}tree[SZ << 2];void update(int p)
{tree[p].maxn = max(tree[p << 1].maxn,tree[p << 1 | 1].maxn);
}void build_seg(int p,int l,int r)
{tree[p].l = l; tree[p].r = r;if(l == r){tree[p].maxn = tree[p].add = 0;return;}int mid = (l + r) >> 1;build_seg(p << 1,l,mid);build_seg(p << 1 | 1,mid + 1,r);update(p);
}void spread(int p)
{if(tree[p].c){tree[p << 1].c = tree[p << 1 | 1].c = tree[p].c;tree[p << 1].maxn = tree[p << 1 | 1].maxn = tree[p].c;tree[p << 1].add = tree[p << 1 | 1].add = 0;tree[p].c = 0;}if(tree[p].add){tree[p << 1].maxn += tree[p].add;   tree[p << 1 | 1].maxn += tree[p].add;if(tree[p << 1].c) tree[p << 1].c += tree[p].add;else tree[p << 1].add += tree[p].add;if(tree[p << 1 | 1].c) tree[p << 1 | 1].c += tree[p].add;else tree[p << 1 | 1].add += tree[p].add;tree[p].add = 0;}
}void change(int p,int l,int r,int d)
{if(l <= tree[p].l && tree[p].r <= r){tree[p].add = 0;tree[p].c = tree[p].maxn = d;return;}spread(p);int mid = (tree[p].l + tree[p].r) >> 1;if(l <= mid) change(p << 1,l,r,d);if(mid < r) change(p << 1 | 1,l,r,d);update(p);
}void add(int p,int l,int r,int d)
{if(l <= tree[p].l && tree[p].r <= r){if(tree[p].c) tree[p].c += d;else tree[p].add += d;tree[p].maxn += d;return;}spread(p);int mid = (tree[p].l + tree[p].r) >> 1;if(l <= mid) add(p << 1,l,r,d);if(mid < r) add(p << 1 | 1,l,r,d);update(p);
}int ask(int p,int l,int r)
{if(l <= tree[p].l && tree[p].r <= r)return tree[p].maxn;spread(p);int mid = (tree[p].l + tree[p].r) >> 1;int ans = 0;if(l <= mid) ans = max(ans,ask(p << 1,l,r));if(mid < r) ans = max(ans,ask(p << 1 | 1,l,r));return ans;
}void find_change(int x,int y,int d)
{int fx = top[x],fy = top[y];while(fx != fy){if(deep[fx] < deep[fy]) swap(x,y),swap(fx,fy);change(1,inseg[fx],inseg[x],d);x = fa[fx]; fx = top[x];}if(x != y){if(deep[x] > deep[y]) swap(x,y);change(1,inseg[x] + 1,inseg[y],d);      }
}void find_add(int x,int y,int d)
{int fx = top[x],fy = top[y];while(fx != fy){if(deep[fx] < deep[fy]) swap(x,y),swap(fx,fy);add(1,inseg[fx],inseg[x],d);x = fa[fx]; fx = top[x];}if(x != y){if(deep[x] > deep[y]) swap(x,y);add(1,inseg[x] + 1,inseg[y],d);     }
}int find_ans(int x,int y)
{int fx = top[x],fy = top[y];int ans = 0;while(fx != fy){if(deep[fx] < deep[fy]) swap(x,y),swap(fx,fy);ans = max(ans,ask(1,inseg[fx],inseg[x]));x = fa[fx]; fx = top[x];}if(x != y){if(deep[x] > deep[y]) swap(x,y);ans = max(ans,ask(1,inseg[x] + 1,inseg[y]));        }return ans;
}struct edge{int f,t,d;
}l[SZ];int main()
{int n;scanf("%d",&n);for(int i = 1;i < n;i ++){scanf("%d%d%d",&l[i].f,&l[i].t,&l[i].d);build_edge(l[i].f,l[i].t); build_edge(l[i].t,l[i].f); }dfs_1(1,0); dfs_2(1,1);build_seg(1,1,n);for(int i = 1;i < n;i ++){if(deep[l[i].f] > deep[l[i].t]) swap(l[i].f,l[i].t);change(1,inseg[l[i].t],inseg[l[i].t],l[i].d);}char opt[10];while(~scanf("%s",opt) && opt[1] != 't'){if(opt[1] == 'h'){int k,w;scanf("%d%d",&k,&w);change(1,inseg[l[k].t],inseg[l[k].t],w);}else if(opt[1] == 'o'){int u,v,w;scanf("%d%d%d",&u,&v,&w);find_change(u,v,w);}else if(opt[1] == 'd'){int u,v,w;scanf("%d%d%d",&u,&v,&w);find_add(u,v,w);            }else if(opt[1] == 'a'){int u,v;scanf("%d%d",&u,&v);printf("%d\n",find_ans(u,v));               }//  for(int i = 1;i <= n;i ++) printf("%d ",find_ans(i,i)); puts("");}return 0;
}

【bzoj1984】【坑】月下“毛景树” 树链剖分相关推荐

  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. CodeForces - 1437G Death DBMS(AC自动机fail树上树链剖分建线段树/暴跳fail)

    题目链接:点击查看 题目大意:给出 n 个模式串,每个模式串初始时的权值为 0,然后有 m 次操作: 1 i x:将第 i 个模式串的权值修改为 x 2 s:给出一个字符串 s,询问字符串 s 作为主 ...

  9. 个人赛C 柠檬树2--树链剖分+维护最值出现次数/LCA

    给一棵树,维护上面两点最短路径中结点的最大值及最大值出现次数 #include <stdio.h> #include<string.h> #include<algorit ...

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

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

最新文章

  1. Python调整图像亮度和饱和度
  2. 张一鸣的微博世界-组织篇
  3. 电气笔记:线路、主变、母线保护讲解
  4. 简单明了区分escape、encodeURI和encodeURIComponent
  5. 学习:java设计模式—工厂模式
  6. Apollo进阶课程㉔丨Apollo 规划技术详解——Motion Planning Environment
  7. 简述div标签和span标签的不同_div与span区别及用法
  8. 使用ubuntu系统中遇到的问题及解决方案
  9. html 轮播_Axure教程:使用动态面板实现轮播图
  10. manjaro配置zsh和oh-my-zsh
  11. java 协议开发_用Java的NIO开发网络协议
  12. linux代码实现进程监控,linux进程监控shell脚本代码
  13. Win7 Server 漏洞修复(CVE-2017-**、CVE-2018-**、CVE-2019-**、CVE-2012-**)
  14. 接口设计方案——接口集成要求
  15. Android设备刷Device-owner说明
  16. 我的电脑图标没了怎么办?3个方法找回消失的图标
  17. Java中Springboot实战之签到功能详解(超全面)
  18. 学习Python的做笔记神器——Jupyter Notebook
  19. 长盛兴业入股宝沃背后:为神州优车相关方 王百因是陆正耀同学
  20. 深度增强学习:走向通用人工智能之路

热门文章

  1. 测试报告包含哪些内容?(超详细,带图)
  2. 【转载】制作一个超精简的WIN7.gho
  3. 冥想---提高元认知能力
  4. SAP 固定资产折旧 计算方法
  5. 深度学习环境配置:2080Ti+Ubuntu16.04+CUDA10+cuDNN7.3+TensorFlow-gpu1.12
  6. 为啥好多公司面试程序员用纸写代码?不会是因为缺少笔记本电脑吧
  7. 期权定价公式的推导(欧式)
  8. mac 截图工具| Snipaste
  9. 用excel打印工资条
  10. qt界面中Pushbutton添加图片的三种显示效果