/**************************************************************
Problem: 1984
User: c20161007
Language: C++
Result: Accepted
Time:4852 ms
Memory:15324 kb
****************************************************************/
#include <bits/stdc++.h>
#define f first
#define s second
#define ll long long
const int MAXN=1e5+10;
using namespace std;
int fa[MAXN],dep[MAXN],num[MAXN],son[MAXN],vis[MAXN],a[MAXN];
vector<pair<int,pair<int,int> > >vec[MAXN];
int n;char str[101];
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar();
return f*x;
}
void dfs(int v,int pre,int deep){
fa[v]=pre;num[v]=1;dep[v]=deep+1;
for(int i=0;i<vec[v].size();i++){
int u=vec[v][i].f;
if(u!=pre){
a[u]=vec[v][i].s.f;vis[vec[v][i].s.s]=u;
dfs(u,v,deep+1);
num[v]+=num[u];
if(son[v]==-1||num[son[v]]<num[u])son[v]=u;
}
}
}
int p[MAXN],tp[MAXN],fp[MAXN],cnt;
void dfs1(int v,int td){
p[v]=++cnt;fp[p[v]]=v;tp[v]=td;
if(son[v]!=-1)dfs1(son[v],td);
for(int i=0;i<vec[v].size();i++){
if(vec[v][i].f!=son[v]&&vec[v][i].f!=fa[v])dfs1(vec[v][i].f,vec[v][i].f);
}
}
int key[MAXN<<2],flag[MAXN<<2],flag1[MAXN<<2];
void push(int x){
if(flag[x]>=0){
flag1[x<<1]=flag1[x<<1|1]=0;flag[x<<1]=flag[x<<1|1]=flag[x];
key[x<<1]=key[x<<1|1]=flag[x];
flag[x]=-1;
}
if(flag1[x]){
flag1[x<<1]+=flag1[x];flag1[x<<1|1]+=flag1[x];
key[x<<1]+=flag1[x];key[x<<1|1]+=flag1[x];
flag1[x]=0;
}
}
void up(int x){key[x]=max(key[x<<1],key[x<<1|1]);return ;}
void built(int rt,int l,int r){
flag[rt]=-1;flag1[rt]=0;
if(l==r){key[rt]=a[fp[l]];return ;}
int mid=(l+r)>>1;
built(rt<<1,l,mid);
built(rt<<1|1,mid+1,r);
up(rt);
}
void update1(int rt,int l,int r,int t,int vul){
if(l==r){key[rt]=vul;return ;}
int mid=(l+r)>>1;
push(rt);
if(t<=mid)update1(rt<<1,l,mid,t,vul);
else update1(rt<<1|1,mid+1,r,t,vul);
up(rt);
}
void update2(int rt,int l,int r,int ql,int qr,int t){
if(ql<=l&&r<=qr){key[rt]=t;flag1[rt]=0;flag[rt]=t;return ;}
int mid=(l+r)>>1;
push(rt);
if(ql<=mid)update2(rt<<1,l,mid,ql,qr,t);
if(qr>mid)update2(rt<<1|1,mid+1,r,ql,qr,t);
up(rt);
}
void update3(int rt,int l,int r,int ql,int qr,int t){
if(ql<=l&&r<=qr){key[rt]+=t;flag1[rt]+=t;return ;}
int mid=(l+r)>>1;
push(rt);
if(ql<=mid)update3(rt<<1,l,mid,ql,qr,t);
if(qr>mid)update3(rt<<1|1,mid+1,r,ql,qr,t);
up(rt);
}
int ans;
void querty(int rt,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){ans=max(ans,key[rt]);return ;}
int mid=(l+r)>>1;
push(rt);
if(ql<=mid)querty(rt<<1,l,mid,ql,qr);
if(qr>mid)querty(rt<<1|1,mid+1,r,ql,qr);
up(rt);
}
int slove(int u,int v,int op,int w){
int uu=tp[u];int vv=tp[v];int ans1=-1;
while(uu!=vv){
if(dep[uu]<dep[vv])swap(uu,vv),swap(u,v);
if(op==1)update2(1,1,n,p[uu],p[u],w);
else if(op==2)update3(1,1,n,p[uu],p[u],w);
else ans=-1,querty(1,1,n,p[uu],p[u]),ans1=max(ans1,ans);
u=fa[uu];uu=tp[u];
}
if(dep[u]>dep[v])swap(u,v);
if(u!=v){
if(op==1)update2(1,1,n,p[son[u]],p[v],w);
else if(op==2)update3(1,1,n,p[son[u]],p[v],w);
else ans=-1,querty(1,1,n,p[son[u]],p[v]),ans1=max(ans1,ans);
}
return ans1;
}
int main(){
n=read();int u,v,vul;
for(int i=1;i<n;i++)u=read(),v=read(),vul=read(),vec[u].push_back(make_pair(v,make_pair(vul,i))),vec[v].push_back(make_pair(u,make_pair(vul,i)));
for(int i=1;i<=n;i++)son[i]=-1;
dfs(1,0,0);dfs1(1,1);built(1,1,n);
//for(int i=1;i<=n;i++)cout<<num[i]<<" ";
//cout<<endl;
//cout<<"sb"<<endl;
while(1){
scanf(" %s",str);
if(str[0]==‘S‘)break;
if(str[1]==‘h‘){
u=read();v=read();update1(1,1,n,p[vis[u]],v);
}
else if(str[1]==‘o‘){
u=read();v=read();vul=read();slove(u,v,1,vul);
}
else if(str[0]==‘A‘){
u=read(),v=read(),vul=read(),slove(u,v,2,vul);
}
else{
u=read();v=read();
printf("%d\n",slove(u,v,3,0));
}
}
return 0;
}
毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。
毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。爬啊爬~爬啊爬~~毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果~~~
“毛景树”上有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之间树枝上毛毛果个数最多有多少个。