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$行,每行三个正整数$U_i,V_i$和$W_i$,第$i+1$行描述第$i$条树枝。表示第$i$条树枝连接节点$U_i$和节点$V_i$,树枝上有$W_i$个毛毛果。

接下来是操作和询问,以“$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

HINT

$1\;\leq\;N\;\leq\;10^5$,操作+询问数目$\;\leq\;10^5$。

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

Solution

把边权转化成边的两端点中深度较大的那个点的点权.

树剖+线段树(注意下传$lazy$的细节,以及没被覆盖时值不该是$0$,因为存在全覆盖成$0$的情况)

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100005
#define M 300005
using namespace std;
struct linetree{
int l,r,m,c,a;
}lt[M];
struct graph{
int nxt,to,w,n;
}e[M];
char c[10];
int g[N],a[N],b[N],w[N],n,u,v,x,cnt;
int f[N],p[N],dep[N],siz[N],son[N],top[N];
inline void addedge(int x,int y,int w,int n){
e[++cnt].nxt=g[x];g[x]=cnt;
e[cnt].to=y;e[cnt].w=w;e[cnt].n=n;
}
inline void dfs1(int u){
int m=0;siz[u]=1;
for(int i=g[u];i;i=e[i].nxt)
if(!dep[e[i].to]){
f[e[i].to]=u;
a[e[i].to]=e[i].w;
b[e[i].n]=e[i].to;
dep[e[i].to]=dep[u]+1;
dfs1(e[i].to);
siz[u]+=siz[e[i].to];
if(siz[e[i].to]>m){
m=siz[e[i].to];
son[u]=e[i].to;
}
}
}
inline void dfs2(int u,int tp){
top[u]=tp;p[u]=++cnt;w[cnt]=a[u];
if(son[u]) dfs2(son[u],tp);
for(int i=g[u];i;i=e[i].nxt)
if(f[u]!=e[i].to&&son[u]!=e[i].to)
dfs2(e[i].to,e[i].to);
}
inline void build(int u,int l,int r){
lt[u].l=l;lt[u].r=r;lt[u].c=-1;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
build(lef,l,mid);build(rig,mid+1,r);
lt[u].m=max(lt[lef].m,lt[rig].m);
}
else lt[u].m=w[lt[u].l];
}
inline void push(int u){
int lef=u<<1,rig=u<<1|1;
if(lt[u].c>=0){
lt[lef].a=lt[rig].a=0;
lt[lef].c=lt[rig].c=lt[u].c;
lt[lef].m=lt[rig].m=lt[u].c;
lt[u].c=-1;
}
if(lt[u].a){
lt[lef].a+=lt[u].a;
lt[rig].a+=lt[u].a;
lt[lef].m+=lt[u].a;
lt[rig].m+=lt[u].a;
lt[u].a=0;
}
}
inline void cover(int u,int l,int r,int k){
if(lt[u].l>=l&&lt[u].r<=r){
lt[u].m=lt[u].c=k;lt[u].a=0;
}
else if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
push(u);
if(l<=mid) cover(lef,l,r,k);
if(r>mid) cover(rig,l,r,k);
lt[u].m=max(lt[lef].m,lt[rig].m);
}
}
inline void add(int u,int l,int r,int k){
if(lt[u].l>=l&&lt[u].r<=r){
lt[u].m+=k;lt[u].a+=k;
}
else if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
push(u);
if(l<=mid) add(lef,l,r,k);
if(r>mid) add(rig,l,r,k);
lt[u].m=max(lt[lef].m,lt[rig].m);
}
}
inline int ask(int u,int l,int r){
if(lt[u].l>=l&&lt[u].r<=r)
return lt[u].m;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1,ret=0;
int mid=(lt[u].l+lt[u].r)>>1;
push(u);
if(l<=mid) ret=max(ret,ask(lef,l,r));
if(r>mid) ret=max(ret,ask(rig,l,r));
return ret;
}
}
inline void cov(int x,int y,int k){
int lt;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
lt=x;x=y;y=lt;
}
cover(1,p[top[x]],p[x],k);
x=f[top[x]];
}
if(p[x]>p[y]){
lt=x;x=y;y=lt;
}
if(p[x]<p[y]) cover(1,p[x]+1,p[y],k);
}
inline void ad(int x,int y,int k){
int lt;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
lt=x;x=y;y=lt;
}
add(1,p[top[x]],p[x],k);
x=f[top[x]];
}
if(p[x]>p[y]){
lt=x;x=y;y=lt;
}
if(p[x]<p[y]) add(1,p[x]+1,p[y],k);
}
inline int q(int x,int y){
int ret=0,lt;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
lt=x;x=y;y=lt;
}
ret=max(ret,ask(1,p[top[x]],p[x]));
x=f[top[x]];
}
if(p[x]>p[y]){
lt=x;x=y;y=lt;
}
if(p[x]<p[y]) ret=max(ret,ask(1,p[x]+1,p[y]));
return ret;
}
inline void Aireen(){
scanf("%d",&n);
for(int i=1,j,k,l;i<n;++i){
scanf("%d%d%d",&j,&k,&l);
addedge(j,k,l,i);addedge(k,j,l,i);
}
dep[1]=1;dfs1(1);
cnt=0;dfs2(1,1);
build(1,1,n);
while(true){
scanf("%s",c);
if(c[1]=='t') return;
if(c[1]=='h'){
scanf("%d%d",&u,&x);
cover(1,p[b[u]],p[b[u]],x);
}
else if(c[1]=='o'){
scanf("%d%d%d",&u,&v,&x);
cov(u,v,x);
}
else if(c[1]=='d'){
scanf("%d%d%d",&u,&v,&x);
ad(u,v,x);
}
else if(c[1]=='a'){
scanf("%d%d",&u,&v);
printf("%d\n",q(u,v));
}
}
}
int main(){
freopen("moon.in","r",stdin);
freopen("moon.out","w",stdout);
Aireen();
fclose(stdin);
fclose(stdout);
return 0;
}

[bzoj1984]月下“毛景树”的更多相关文章

  1. BZOJ1984: 月下“毛景树”

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 713  Solved: 245[Submit][Status] Descri ...

  2. [BZOJ1984]月下“毛景树”解题报告|树链剖分

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

  3. 【树链剖分】【分块】【最近公共祖先】【块状树】bzoj1984 月下“毛景树”

    裸题,但是因为权在边上,所以要先把边权放到这条边的子节点上,然后进行链更新/查询的时候不能更新/查询其lca. #include<cstdio> #include<cmath> ...

  4. 2018.10.27 bzoj1984: 月下“毛景树”(树链剖分)

    传送门 唉蒟蒻又退化了,这道sb题居然做了20min,最后发现是updcovupdcovupdcov写成了updaddupdaddupdadd我还能说什么233233233 就是让你转边权为点权之后, ...

  5. 【BZOJ1984】月下“毛景树” 树链剖分+线段树

    [BZOJ1984]月下"毛景树" Description 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校 ...

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

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

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

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

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

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

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

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

随机推荐

  1. Integer.parseInt(String s) 和 Integer.valueOf(String s) 的区别

    通过查看java.lang.Integer的源码可以发现, 它们最终调用的都是 /** * Parses the string argument as a signed integer in the ...

  2. Delphi常用系统函数总结

    Delphi常用系统函数总结 字符串处理函数 Unit System 函数原型 function Concat(s1 [, s2,..., sn]: string): string; 说明 与 S : ...

  3. 添加JSON Data到已经存在的JSON文件中

    早上在学习<Post model至Web Api创建或是保存数据>http://www.cnblogs.com/insus/p/4343833.html ,如果你第二添加时,json文件得 ...

  4. 协程python

    python中协程 在引出协成概念之前先说说python的进程和线程. 进程: 进程是正在执行程序实例.执行程序的过程中,内核会讲程序代码载入虚拟内存,为程序变量分配空间,建立 bookkeeping ...

  5. codevs2010 求后序遍历

    难度等级:白银 2010 求后序遍历 题目描述 Description 输入一棵二叉树的先序和中序遍历序列,输出其后序遍历序列. 输入描述 Input Description 共两行,第一行一个字符串 ...

  6. 关于viewpager 里嵌套 listview 同时实现翻页功能的“java.lang.IllegalStateException: The specified child..."异常处理

    这几天做项目用到了ViewPager,因为它可以实现左右划动多个页面的效果,然后 再每个页面里使用ListView,运行时总是出现”PagerAdapter java.lang.IllegalStat ...

  7. 如何使用 UC浏览器开发者版 进行移动端调试

    在 如何用 fiddler 代理调试本地手机页 一文中我们了解了如何用手机查看 PC 端写的网页(本地),但是我们只能看到页面效果,如果哪段 js 挂了,那部分样式失效了,我们该如何进行调试呢?今天为 ...

  8. JavaScript函数劫持

    一.为什么我会写这篇文章 这篇文章其实是在一个偶然的机会下发现了居然有JavaScript劫持这种东西,虽然这种东西在平时用的比较少,而且一般实用价值不高,但是在一些特殊的情况下还是要使用到的,所以在 ...

  9. 单从Advice(通知)实现AOP

    如果你在实际开发中没感觉到OOP的一些缺陷,就不要往下看了! 如果你不了解AOP,或类似AOP的思路,请先去了解一下AOP相关的认识. 如果你是概念党,或是经验党,或是从众党,也请不要看了! 我实现的 ...

  10. BroadcoastReceiver之短信到来监听和获取内容

    废话就不说了,新建类继承,然后配置Manifest.xml:如下 <!--需要给一个接收短信的权限 --> <uses-permission android:name="a ...