【题解】
树链剖分模板题。。
#include<cstdio>
#include<algorithm>
#include<queue>
#define N 500010
#define rg register
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((a[u].l+a[u].r)>>1)
#define len(x) (a[x].r-a[x].l+1)
using namespace std;
int n,m,rt,num,x,y,z,fa[N],dfn[N],dep[N],size[N],heavy[N],top[N];
vector<int>son[N];
struct tree{
int l,r;
long long sum,del;
}a[N];
inline int read(){
int k=0,f=1; char c=getchar();
while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
return k*f;
}
inline void pushup(int u){
a[u].sum=a[ls].sum+a[rs].sum;
}
inline void pushdown(int u){
if(!a[u].del) return; long long d=a[u].del; a[u].del=0;
a[ls].del+=d; a[ls].sum+=d*len(ls);
a[rs].del+=d; a[rs].sum+=d*len(rs);
}
void build(int u,int l,int r){
a[u].l=l; a[u].r=r; a[u].sum=a[u].del=0;
if(l<r) build(ls,l,mid),build(rs,mid+1,r);
}
void update(int u,int l,int r,long long d){
if(l<=a[u].l&&a[u].r<=r){
a[u].del+=d; a[u].sum+=d*len(u); return;
}
pushdown(u);
if(l<=mid) update(ls,l,r,d);
if(r>mid) update(rs,l,r,d);
pushup(u);
}
long long query(int u,int l,int r){
if(l<=a[u].l&&a[u].r<=r) return a[u].sum;
pushdown(u); long long ret=0;
if(l<=mid) ret+=query(ls,l,r);
if(r>mid) ret+=query(rs,l,r);
return ret;
}
void dfs1(int x){
size[x]=1; dep[x]=dep[fa[x]]+1;
for(rg int i=0;i<son[x].size();i++){
dfs1(son[x][i]);
size[x]+=size[son[x][i]];
if(size[son[x][i]]>size[heavy[x]]) heavy[x]=son[x][i];
}
}
void dfs2(int x,int tp){
top[x]=tp; dfn[x]=++num;
if(heavy[x]) dfs2(heavy[x],tp);
for(rg int i=0;i<son[x].size();i++)
if(son[x][i]!=heavy[x]) dfs2(son[x][i],son[x][i]);
}
int main(){
n=read();
for(rg int i=1;i<n;i++){
int x=read(),y=read();
fa[y]=x; son[x].push_back(y);
if(x==0) rt=x;
}
dfs1(rt); dfs2(rt,rt);
// for(rg int i=0;i<=n;i++) printf("%d ",size[i]); puts("");
// for(rg int i=0;i<=n;i++) printf("%d ",dfn[i]); puts("");
build(1,1,n);
m=read();
while(m--){
char c=getchar();
while(c!='A'&&c!='Q')c=getchar();
if(c=='A'){
x=read(),y=read(),z=read();
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(1,dfn[top[x]],dfn[x],z);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,dfn[x],dfn[y],z);
}
else x=read(),printf("%lld\n",query(1,dfn[x],dfn[x]+size[x]-1));
}
return 0;
}