MnZn刚学树剖,菜菜,大佬,带带/kk
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<bitset>
#include<map>
#include<unordered_map>
#define int long long
using namespace std;
typedef long long ll;
const int N=2e5+5;
struct Edge{
int v,w,id,next;
}edge[N];
string s;
int n,tot=1,cnt=0;
unordered_map <int,int> rec;
int head[N],dep[N],f[N],top[N],dfn[N],siz[N],son[N],w[N],nw[N];
inline void add(int u,int v,int w,int id){
edge[++tot]=(Edge){v,w,id,head[u]},head[u]=tot;
}
inline int read(){
int s=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') {f=-1;} ch=getchar();}
while(isdigit(ch)) {s=(s<<1)+(s<<3)+ch-'0'; ch=getchar();}
return s*f;
}
inline void write(int x){
int top=0,sta[35];
while(x) {sta[top++]=x%10,x/=10;}
while(top) {putchar(sta[--top]+'0');}
}
inline void dfs1(int u,int fa)
{
dep[u]=dep[fa]+1;
f[u]=fa,siz[u]=1;int Maxson=-1;
for (int i=head[u];i;i=edge[i].next)
{
int v=edge[i].v;
if (v==fa) continue;
w[v]=edge[i].w;
dfs1(v,u);siz[u]+=siz[v];
if (siz[v]>Maxson) Maxson=siz[v],son[u]=v;
}
}
inline void dfs2(int u,int fa)
{
top[u]=fa;
dfn[u]=++cnt;nw[cnt]=w[u];
if (!son[u]) return ;
dfs2(son[u],fa);
for (int i=head[u];i;i=edge[i].next)
{
int v=edge[i].v;
if (v==f[u] || v==son[u]) continue;
dfs2(v,v);
}
}
namespace SegmentTree{
#define ls(u) u<<1
#define rs(u) u<<1 | 1
struct Info{
int val,lazy,tag;
}seg[N<<2];
inline void pushdown(int u)
{
if (seg[u].tag!=-1)
{
int &c=seg[u].tag;
seg[ls(u)].val=c;seg[rs(u)].val=c;
seg[ls(u)].tag=c,seg[ls(u)].tag=c;
seg[ls(u)].lazy=0,seg[rs(u)].lazy=0;
c=-1;
}
if (seg[u].lazy)
{
int &c=seg[u].lazy;
seg[ls(u)].val+=c;seg[rs(u)].val+=c;
seg[ls(u)].lazy+=c;seg[rs(u)].lazy+=c;
c=0;
}
}
inline void pushup(int u) {seg[u].val=max(seg[ls(u)].val,seg[rs(u)].val);}
inline void build(int u,int l,int r)
{
seg[u].tag=-1;
seg[u].lazy=0;
if (l==r)
{
seg[u].val=nw[l];
return ;
}
int mid=(l+r) >> 1;
build(ls(u),l,mid);
build(rs(u),mid+1,r);
pushup(u);
}
inline void Modify(int u,int s,int t,int l,int r,int c)
{
if (l<=s && r>=t)
{
seg[u].val+=c;
seg[u].lazy+=c;
return ;
}
int mid=(s+t) >> 1;
pushdown(u);
if (l<=mid) Modify(ls(u),s,mid,l,r,c);
if (r>mid) Modify(rs(u),mid+1,t,l,r,c);
pushup(u);
}
inline void Change(int u,int s,int t,int l,int r,int c)
{
if (l<=s && r>=t)
{
seg[u].val=c;
seg[u].tag=c;
seg[u].lazy=0;
return ;
}
int mid=(s+t) >> 1;
pushdown(u);
if (l<=mid) Change(ls(u),s,mid,l,r,c);
if (r>mid) Change(rs(u),mid+1,t,l,r,c);
pushup(u);
}
inline int Maxquery(int u,int s,int t,int l,int r)
{
if (l<=s && r>=t) {return seg[u].val;}
int mid=(s+t) >> 1,res=0;
pushdown(u);
if (l<=mid) res=max(res,Maxquery(ls(u),s,mid,l,r));
if (r>mid) res=max(res,Maxquery(rs(u),mid+1,t,l,r));
pushup(u);
return res;
}
#undef ls
#undef rs
}
using namespace SegmentTree;
inline int PathMax(int u,int v)
{
int ans=0;
while (top[u]!=top[v])
{
if (dep[top[u]]<dep[top[v]]) swap(u,v);
ans=max(ans,Maxquery(1,1,n,dfn[top[u]],dfn[u]));u=f[top[u]];
}
if (dep[u]>dep[v]) swap(u,v);
ans=max(ans,Maxquery(1,1,n,dfn[u],dfn[v]));
return ans;
}
inline void PathModify(int u,int v,int c)
{
while (top[u]!=top[v])
{
if (dep[top[u]]<dep[top[v]]) swap(u,v);
Modify(1,1,n,dfn[top[u]],dfn[u],c),u=f[top[u]];
}
if (dep[u]>dep[v]) swap(u,v);
Modify(1,1,n,dfn[u],dfn[v],c);
}
inline void PathCover(int u,int v,int c)
{
while (top[u]!=top[v])
{
if (dep[top[u]]<dep[top[v]]) swap(u,v);
Change(1,1,n,dfn[top[u]],dfn[u],c),u=f[top[u]];
}
if (dep[u]>dep[v]) swap(u,v);
Change(1,1,n,dfn[u],dfn[v],c);
}
inline void EdgeCover(int u,int c){
Change(1,1,n,dfn[u],dfn[u],c);
}
signed main()
{
n=read();
for (int i=1;i<=n-1;i++)
{
int u=read(),v=read(),w=read();
add(u,v,w,i),add(v,u,w,i);
}
dfs1(1,1);
dfs2(1,1);
build(1,1,n);
while (true)
{
cin>>s;if (s=="Stop") break;
if (s=="Max")
{
int u=read(),v=read();
printf("%lld\n",PathMax(u,v));
}
if (s=="Cover")
{
int u=read(),v=read(),c=read();
PathCover(u,v,c);
}
if (s=="Add")
{
int u=read(),v=read(),c=read();
PathModify(u,v,c);
}
if (s=="Change")
{
int u=read(),c=read();
EdgeCover(u,c);
}
}
return 0;
}