目测可能是死循环?
// Problem: P3833 [SHOI2012]魔法树
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3833
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)
#include <bits/stdc++.h>
using namespace std;
#define M 100005
#define ls (i*2)
#define rs (i*2+1)
#define mid ((l+r)/2)
#define int long long
int n,U,V,m,x,y,z,d[M],cntp,fa[M],son[M],top[M],siz[M],id[M];
string opt;
vector<int>road[M];
struct node
{
int len,s,laz;
}t[M*9];
void pd(int i)
{
if(t[i].laz==0) return;
int la=t[i].laz;
t[ls].laz+=la;t[rs].laz+=la;
t[ls].s+=t[ls].len*la;
t[rs].s+=t[rs].len*la;
t[i].laz=0;
}
void p(int i) {t[i].s=t[ls].s+t[rs].s;}
void dfs1(int x)
{
int MSON=-1,MNUM=0;
siz[x]=1;
for(int i=0;i<road[x].size();i++)
{
d[road[x][i]]=d[x]+1;
dfs1(road[x][i]);
siz[x]+=siz[road[x][i]];
if(siz[road[x][i]]>MNUM)
{
MNUM=siz[road[x][i]];
MSON=road[x][i];
}
}
son[x]=MSON;
}
void dfs2(int x,int y)
{
id[x]=++cntp;
top[x]=y;
if(son[x]==-1) return;
dfs2(son[x],y);
for(int i=0;i<road[x].size();i++)
{
if(son[x]==road[x][i]) continue;
dfs2(road[x][i],road[x][i]);
}
}
void build(int l,int r,int i)
{
t[i].len=(r-l+1);t[i].laz=t[i].s=0;
if(l==r) return;
build(l,mid,ls);build(mid+1,r,rs);
}
void plused(int fl,int fr,int v,int l,int r,int i)
{
pd(i);
if(fl<=l&&fr>=r)
{
t[i].laz+=v;
t[i].s+=t[i].len*v;
return;
}
if(mid>=fl) plused(fl,fr,v,l,mid,ls);
if(mid<fr) plused(fl,fr,v,mid+1,r,rs);
p(i);
}
int query(int fl,int fr,int l,int r,int i)
{
int res=0;pd(i);
if(fl<=l&&fr>=r) return t[i].s;
if(mid>=fl) res+=query(fl,fr,l,mid,ls);
if(mid<fr) res+=query(fl,fr,mid+1,r,rs);
return res;
}
void Plus(int fx,int fy,int fz)
{
while(top[fx]!=top[fy])
{
if(d[top[fx]]<d[top[fy]]) swap(fx,fy);
plused(id[top[fx]],id[fx],fz,1,n,1);x=fa[top[fx]];
}
if(d[fx]<d[fy]) swap(fx,fy);
plused(id[fy],id[fx],fz,1,n,1);
}
void Query(int fx)
{
cout<<query(id[fx],id[fx]+siz[fx]-1,1,n,1)<<endl;
}
signed main()
{
cin>>n;
for(int i=1;i<n;i++)
{
cin>>U>>V;U++;V++;
road[U].push_back(V);
fa[V]=U;
}
cin>>m;
dfs1(1);dfs2(1,1);build(1,n,1);
for(int i=1;i<=m;i++)
{
cin>>opt;
if(opt=="A")
{
cin>>x>>y>>z;
x++;y++;
Plus(x,y,z);
}
else
{
cin>>x;x++;
Query(x);
}
}
return 0;
}
/*
树剖模板
*/