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

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

树剖裸题,注意边权转点权,

这里要找到编号为\(k\)的边所连的深度深的点.

我们把边权传递给下面深度较深的点,是可以保证每个点价值唯一的.

只需要维护区间覆盖和区间最大值即可了.

注意区间覆盖的优先级高于区间加

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cctype>
#define int long long
#define ls o<<1
#define rs o<<1|1
#define R register
#define N 100008
using namespace std;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int head[N],tot;
struct cod{int u,v,w,fr;}edge[N<<2];
inline void add(int x,int y,int z)
{
edge[++tot].u=head[x];
edge[tot].fr=x;
edge[tot].v=y;
edge[tot].w=z;
head[x]=tot;
}
int size[N],son[N],f[N],depth[N],val[N];
void dfs1(int u,int fa,int dis)
{
val[u]=dis;f[u]=fa;size[u]=1;depth[u]=depth[fa]+1;
for(R int i=head[u];i;i=edge[i].u)
{
if(edge[i].v==fa)continue;
dfs1(edge[i].v,u,edge[i].w);
size[u]+=size[edge[i].v];
if(son[u]==-1 or size[son[u]]<size[edge[i].v])
son[u]=edge[i].v;
}
}
int dfn[N],fdfn[N],idx,top[N];
void dfs2(int u,int t)
{
top[u]=t;dfn[u]=++idx;fdfn[idx]=u;
if(son[u]==-1)return;
dfs2(son[u],t);
for(R int i=head[u];i;i=edge[i].u)
{
if(dfn[edge[i].v])continue;
dfs2(edge[i].v,edge[i].v);
}
}
int n;
char s[8];
int tr[N<<2],tg1[N<<2],tg2[N<<2];
inline void up(int o)
{
tr[o]=max(tr[ls],tr[rs]);
return;
}
inline void down(int o,int l,int r)
{
if(tg1[o]>=0)
{
tr[ls]=tr[rs]=tg1[ls]=tg1[rs]=tg1[o];
tg1[o]=-1;tg2[ls]=tg2[rs]=0;
}
if(tg2[o])
{
tr[ls]+=tg2[o];tr[rs]+=tg2[o];
tg2[ls]+=tg2[o];tg2[rs]+=tg2[o];
tg2[o]=0;
}
}
void build(int o,int l,int r)
{
tg1[o]=-1;
if(l==r)
{
tr[o]=val[fdfn[l]];
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
up(o);
}
void change1(int o,int l,int r,int x,int y,int k)//区间覆盖.
{
if(x<=l and y>=r)
{
tr[o]=tg1[o]=k;
tg2[o]=0;
return;
}
down(o,l,r);
int mid=(l+r)>>1;
if(x<=mid)change1(ls,l,mid,x,y,k);
if(y>mid)change1(rs,mid+1,r,x,y,k);
up(o);
}
void change2(int o,int l,int r,int x,int y,int k)//区间增加.
{
if(x<=l and y>=r)
{
tr[o]+=k;tg2[o]+=k;
return;
}
down(o,l,r);
int mid=(l+r)>>1;
if(x<=mid)change2(ls,l,mid,x,y,k);
if(y>mid)change2(rs,mid+1,r,x,y,k);
up(o);
}
int query(int o,int l,int r,int x,int y)
{
if(x<=l and y>=r)return tr[o];
down(o,l,r);
int mid=(l+r)>>1,res=-2147483647;
if(x<=mid)res=max(res,query(ls,l,mid,x,y));
if(y>mid)res=max(res,query(rs,mid+1,r,x,y));
return res;
}
inline void tchange1(int x,int y,int k)
{
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(depth[fx]>depth[fy])
{
change1(1,1,idx,dfn[fx],dfn[x],k);
x=f[fx];
}
else
{
change1(1,1,idx,dfn[fy],dfn[y],k);
y=f[fy];
}
fx=top[x],fy=top[y];
}
if(x==y)return;
if(dfn[x]>dfn[y])swap(x,y);
change1(1,1,idx,dfn[x]+1,dfn[y],k);
return;
}
inline void tchange2(int x,int y,int k)
{
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(depth[fx]>depth[fy])
{
change2(1,1,idx,dfn[fx],dfn[x],k);
x=f[fx];
}
else
{
change2(1,1,idx,dfn[fy],dfn[y],k);
y=f[fy];
}
fx=top[x],fy=top[y];
}
if(x==y)return;
if(dfn[x]>dfn[y])swap(x,y);
change2(1,1,idx,dfn[x]+1,dfn[y],k);
return;
}
inline int tquery(int x,int y)
{
int fx=top[x],fy=top[y],res=-2147483647;
while(fx!=fy)
{
if(depth[fx]>depth[fy])
{
res=max(res,query(1,1,idx,dfn[fx],dfn[x]));
x=f[fx];
}
else
{
res=max(res,query(1,1,idx,dfn[fy],dfn[y]));
y=f[fy];
}
fx=top[x],fy=top[y];
}
if(x==y)return res;
if(dfn[x]>dfn[y])swap(x,y);
res=max(res,query(1,1,idx,dfn[x]+1,dfn[y]));
return res;
}
signed main()
{
in(n);memset(son,-1,sizeof son);
for(R int i=1,x,y,z;i<n;i++)
{
in(x),in(y),in(z);
add(x,y,z),add(y,x,z);
}
dfs1(1,0,0);dfs2(1,1);build(1,1,idx);
while(1)
{
scanf("%s",s);
if(s[0]=='S')break;
R int x,y,k;
if(s[0]=='C' and s[1]=='h')
{
in(x),in(k);
x*=2;
if(depth[edge[x].fr]>depth[edge[x].v])
x=edge[x].fr;
else x=edge[x].v;
change1(1,1,idx,dfn[x],dfn[x],k);
}//单点修改
else if(s[0]=='C' and s[1]=='o')
{in(x),in(y),in(k);tchange1(x,y,k);}//区间覆盖
else if(s[0]=='A')//区间增加
{in(x),in(y),in(k);tchange2(x,y,k);}
else if(s[0]=='M')
{in(x),in(y);printf("%lld\n",tquery(x,y));}
}
}

最新文章

  1. ArcGIS Server GP服务发布与测试(基础版)
  2. SSMTP—让Linux系统从Office 365发送邮件
  3. &lt;meta http-equiv=&quot;pragma&quot; content=&quot;no-cache&quot;/&gt;-备
  4. UVa 10294 Arif in Dhaka (First Love Part 2)(置换)
  5. 手机站点开发及手机中图片加速显示img的Canvas方法
  6. 去除Eclipse中js报错的问题
  7. linux CentOS6.5 yum安装mysql 5.6
  8. 关于Java泛型&quot;擦除&quot;的一点思考
  9. 一文读懂MapReduce
  10. Linux chmod命令用法
  11. django——url(路由)配置
  12. WPF控件库:文字按钮的封装
  13. 第三章 JQuery: HelloWorld--常见方法--css--选择器--筛选器--属性--效果--事件--数组操作--字符串操作--对象转换
  14. 机器学习基石笔记:10 Logistic Regression
  15. SSM(Spring +SpringMVC + Mybatis)框架搭建
  16. multi-head attention
  17. 基于vue实现一个简单的MVVM框架(源码分析)
  18. Xcode常见设置
  19. JQuery Ajax 在asp.net中使用总结
  20. bit byte哪些事

热门文章

  1. Pascal 杨辉三角
  2. Pascal “内存病毒”(骗人的)
  3. USACO Section1.2 Palindromic Squares 解题报告
  4. 【Hazard of Overfitting】林轩田机器学习基石
  5. wxPython 安装 及参考文档
  6. Python全栈 MySQL 数据库 (SQL查询、备份、恢复、授权)
  7. (原)Unreal 渲染模块引言Temp
  8. 一步步精通NodeJs的简单实例
  9. EF异常:对一个或多个实体的验证失败
  10. 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分