#include<bits/stdc++.h>
#define ll long long
#define mid ((l+r)>>1)
#define ls (rt<<1)
#define rs (rt<<1|1)
using namespace std;
inline int read(){
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s;
}
inline void write(ll x){
if(x>=10)write(x/10);
putchar(x%10+48);
}
const int N=100501;
int n,m;
vector<int>e[N];
int fa[N],dep[N],tp[N],tot,dfn[N],siz[N],son[N],bot[N],id[N];
struct HEAP{
priority_queue<ll>del,q;
inline void POP(){
while(del.size()&&del.top()==q.top()){
del.pop(),q.pop();
}
}
inline void PUSH(ll x){
POP();
q.push(x);
}
inline void DEL(ll x){
del.push(x);
}
inline ll fi(){
POP();
return q.top();
}
inline ll se(){
ll x=fi();
DEL(x);
ll y=fi();
PUSH(x);
return y;
}
}ANS,q[N];
struct node{
int l,r;
ll maxl,maxr,maxn,sum,lz;
node(){l=r=maxl=maxr=maxn=sum=lz=0;}
};
node operator +(const node &a,const node &b){
node c;
c.l=a.l,c.r=b.r;
c.maxn=max(max(a.maxn,b.maxn),a.maxr+b.maxl);
c.maxl=max(a.maxl,a.sum+b.maxl);
c.maxr=max(b.maxr,b.sum+a.maxr);
c.sum=a.sum+b.sum;
return c;
}
struct SEG{
node t[N<<2];
inline void upd(int rt,int p){
int x=id[p];
ll fi=q[x].fi(),se=q[x].se();
t[rt].maxl=fi+t[rt].sum;
t[rt].maxr=fi+t[rt].sum+t[rt].lz;
t[rt].maxn=fi+se+t[rt].sum+t[rt].lz;
}
inline void build(int rt,int l,int r){
if(l==r){
upd(rt,l);
return;
}
build(ls,l,mid),build(rs,mid+1,r);
t[rt]=t[ls]+t[rs];
}
inline void psh(int rt,int x){
t[rt].maxn+=x,t[rt].maxr+=x,t[rt].lz+=x;
}
inline void pshlz(int rt){
if(t[rt].lz){
psh(ls,t[rt].lz),psh(rs,t[rt].lz);
t[rt].lz=0;
}
}
inline void modify(int rt,int l,int r,int L,int R,ll x){
if(L<=l&&r<=R){
psh(rt,x);
return;
}
pshlz(rt);
if(L<=mid)modify(ls,l,mid,L,R,x);
if(mid<R)modify(rs,mid+1,r,L,R,x);
t[rt]=t[ls]+t[rs];
}
inline void modify(int rt,int l,int r,int x,ll p){
t[rt].sum+=p;
if(l==r){
t[rt].maxr+=p,t[rt].maxn+=p,t[rt].maxl+=p;
return;
}
pshlz(rt);
if(x<=mid)modify(ls,l,mid,x,p);
else modify(rs,mid+1,r,x,p);
t[rt]=t[ls]+t[rs];
}
inline void change(int rt,int l,int r,int x){
if(l==r){
upd(rt,x);
return;
}
pshlz(rt);
if(x<=mid)change(ls,l,mid,x);
else change(rs,mid+1,r,x);
t[rt]=t[ls]+t[rs];
}
inline node query(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R)return t[rt];
pshlz(rt);
if(L>mid)return query(rs,mid+1,r,L,R);
else if(R<=mid)return query(ls,l,mid,L,R);
else return query(ls,l,mid,L,mid)+query(rs,mid+1,r,mid+1,R);
}
}T;
struct queryoption{
int x,y,w;
}op[N];
inline void dfs(int x){
siz[x]=1;
for(auto y:e[x]){
if(y!=fa[x]){
fa[y]=x;
dep[y]=dep[x]+1;
dfs(y);
siz[x]+=siz[y];
if(siz[y]>siz[son[x]])son[x]=y;
}
}
}
inline void dfs1(int x,int topp){
dfn[x]=++tot;
id[tot]=x;
tp[x]=topp;
bot[x]=x;
if(son[x])dfs1(son[x],topp),bot[x]=bot[son[x]];
for(auto y:e[x]){
if(y!=fa[x]&&y!=son[x])dfs1(y,y);
}
}
inline int get_lca(int u,int v){
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]])swap(u,v);
u=fa[tp[u]];
}
return dep[u]<dep[v]?u:v;
}
inline void add(int u,int v){
node c;
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]])swap(u,v);
c=T.query(1,1,n,dfn[tp[u]],dfn[bot[u]]);
ANS.PUSH(c.maxn);
u=fa[tp[u]];
}
c=T.query(1,1,n,dfn[tp[u]],dfn[bot[u]]);
ANS.PUSH(c.maxn);
}
inline void del(int u,int v){
node c;
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]])swap(u,v);
c=T.query(1,1,n,dfn[tp[u]],dfn[bot[u]]);
ANS.DEL(c.maxn);
u=fa[tp[u]];
}
c=T.query(1,1,n,dfn[tp[u]],dfn[bot[u]]);
ANS.DEL(c.maxn);
}
inline void modify(int u,int v,int w){
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]])swap(u,v);
T.modify(1,1,n,dfn[tp[u]],dfn[u],w);
u=fa[tp[u]];
}
if(dep[u]>dep[v])swap(u,v);
T.modify(1,1,n,dfn[u],dfn[v],w);
}
inline void solve(int u,int v,int w){
int lca=get_lca(u,v);
node c;
for(int i=tp[lca];i;i=tp[fa[i]]){
c=T.query(1,1,n,dfn[i],dfn[bot[i]]);
if(fa[i])q[fa[i]].DEL(c.maxl);
if(i!=tp[lca]){
ANS.DEL(c.maxn);
}
}
del(u,v);
T.modify(1,1,n,dfn[lca],w);
modify(u,v,w);
modify(lca,lca,-w);
add(u,v);
for(int i=tp[lca];i;i=tp[fa[i]]){
c=T.query(1,1,n,dfn[i],dfn[bot[i]]);
if(fa[i])q[fa[i]].PUSH(c.maxl),T.change(1,1,n,dfn[fa[i]]);
if(i!=tp[lca]){
ANS.PUSH(c.maxn);
}
}
}
int main(){
n=read(),m=read();
for(int i=1;i<n;i++){
int x=read(),y=read();
e[x].push_back(y),e[y].push_back(x);
}
for(int i=1;i<=n;i++)q[i].PUSH(0),q[i].PUSH(0);
dfs(1);
dfs1(1,1);
for(int i=1;i<=n;i++)if(i==tp[i])ANS.PUSH(0);
char ch;
T.build(1,1,n);
for(int i=1;i<=m;i++){
while(ch=getchar(),ch!='-'&&ch!='+');
if(ch=='+'){
op[i].x=read(),op[i].y=read(),op[i].w=read();
solve(op[i].x,op[i].y,op[i].w);
}
else{
int x=read();
solve(op[x].x,op[x].y,-op[x].w);
}
write(ANS.fi());
puts("");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】