树剖板子……
一个路径加和,线段树上打标记。一个子树询问,dfs的时候记录一下子树的区间就行
1 // luogu-judger-enable-o2 2 //minamoto 3 #include<bits/stdc++.h> 4 #define ll long long 5 using namespace std; 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 7 char buf[1<<21],*p1=buf,*p2=buf; 8 inline int read(){ 9 #define num ch-'0' 10 char ch;bool flag=0;int res; 11 while(!isdigit(ch=getc())) 12 (ch=='-')&&(flag=true); 13 for(res=num;isdigit(ch=getc());res=res*10+num); 14 (flag)&&(res=-res); 15 #undef num 16 return res; 17 } 18 inline char getop(){char ch;while((ch=getc())!='A'&&ch!='Q');return ch;} 19 char sr[1<<21],z[20];int C=-1,Z; 20 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 21 inline void print(ll x){ 22 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 23 while(z[++Z]=x%10+48,x/=10); 24 while(sr[++C]=z[Z],--Z);sr[++C]='\n'; 25 } 26 const int N=1e5+5; 27 int head[N],Next[N],ver[N],tot; 28 inline void add(int u,int v){ 29 ver[++tot]=v,Next[tot]=head[u],head[u]=tot; 30 } 31 int L[N],R[N],top[N],fa[N],dep[N],sz[N],son[N],cnt,n,m; 32 void dfs1(int u){ 33 sz[u]=1,dep[u]=dep[fa[u]]+1; 34 for(int i=head[u];i;i=Next[i]){ 35 int v=ver[i]; 36 fa[v]=u,dfs1(v),sz[u]+=sz[v]; 37 if(sz[son[u]]<sz[v]) son[u]=v; 38 } 39 } 40 void dfs2(int u,int t){ 41 top[u]=t,L[u]=++cnt; 42 if(son[u]){ 43 dfs2(son[u],t); 44 for(int i=head[u];i;i=Next[i]) 45 if(ver[i]!=son[u]) dfs2(ver[i],ver[i]); 46 } 47 R[u]=cnt; 48 // printf("%d %d %d %d\n",u,L[u],R[u],son[u]); 49 } 50 ll tag[N<<2],sum[N<<2];int size[N<<2]; 51 #define ls (p<<1) 52 #define rs (p<<1|1) 53 inline void upd(int p){sum[p]=sum[ls]+sum[rs];} 54 inline void pd(int p){ 55 if(tag[p]){ 56 tag[ls]+=tag[p],tag[rs]+=tag[p]; 57 sum[ls]+=tag[p]*size[ls],sum[rs]+=tag[p]*size[rs]; 58 tag[p]=0; 59 } 60 } 61 void build(int p,int l,int r){ 62 size[p]=r-l+1;if(l==r) return; 63 int mid=(l+r)>>1; 64 build(ls,l,mid),build(rs,mid+1,r); 65 } 66 void update(int p,int l,int r,int ql,int qr,int x){ 67 if(ql<=l&&qr>=r) return (void)(tag[p]+=x,sum[p]+=1ll*x*size[p]); 68 int mid=(l+r)>>1;pd(p); 69 if(ql<=mid) update(ls,l,mid,ql,qr,x); 70 if(qr>mid) update(rs,mid+1,r,ql,qr,x); 71 upd(p); 72 } 73 ll query(int p,int l,int r,int ql,int qr){ 74 if(ql<=l&&qr>=r) return sum[p]; 75 int mid=(l+r)>>1;ll res=0;pd(p); 76 if(ql<=mid) res+=query(ls,l,mid,ql,qr); 77 if(qr>mid) res+=query(rs,mid+1,r,ql,qr); 78 return res; 79 } 80 void change(int u,int v,int x){ 81 while(top[u]!=top[v]){ 82 if(dep[top[u]]<dep[top[v]]) swap(u,v); 83 update(1,1,n,L[top[u]],L[u],x),u=fa[top[u]]; 84 } 85 if(dep[u]<dep[v]) swap(u,v); 86 update(1,1,n,L[v],L[u],x); 87 } 88 int main(){ 89 // freopen("testdata.in","r",stdin); 90 n=read(); 91 for(int i=1,u,v;i<n;++i) 92 u=read()+1,v=read()+1,add(u,v); 93 dfs1(1),dfs2(1,1),build(1,1,n); 94 m=read(); 95 while(m--){ 96 char op=getop();int u,v,d; 97 if(op=='A') u=read()+1,v=read()+1,d=read(),change(u,v,d); 98 else u=read()+1,print(query(1,1,n,L[u],R[u])); 99 } 100 Ot(); 101 return 0; 102 }