警示后人:十年OI迷迷茫茫,不开long long见祖宗
此题我刚好100行代码,百年难遇:
#include<bits/stdc++.h>
#define int long long
#define N 100010
using namespace std;
int n,q,f[N],d[N],size[N],top[N],son[N],id[N],rk[N],cnt,sum[N<<2],add[N<<2];
vector<int> w[N];
void dfs1(int now){
d[now]=d[f[now]]+1;
size[now]=1;
for(int i=0;i<w[now].size();i++){
int t=w[now][i];
dfs1(t);
size[now]+=size[t];
if(size[t]>size[son[now]]) son[now]=t;
}
}
void dfs2(int now,int t){
top[now]=t;
id[now]=++cnt;
rk[cnt]=now;
if(son[now]) dfs2(son[now],t);
for(int i=0;i<w[now].size();i++){
int p=w[now][i];
if(son[now]!=p) dfs2(p,p);
}
}
void push_up(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void push_down(int rt,int m){
if(add[rt]){
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
sum[rt<<1]+=add[rt]*(m-(m>>1));
sum[rt<<1|1]+=add[rt]*(m>>1);
add[rt]=0;
}
}
void update(int l,int r,int rt,int a,int b,int c){
if(a<=l&&b>=r){
add[rt]+=c;
sum[rt]+=c*(r-l+1);
return;
}
push_down(rt,r-l+1);
int mid=l+r>>1;
if(a<=mid) update(l,mid,rt<<1,a,b,c);
if(b>mid) update(mid+1,r,rt<<1|1,a,b,c);
push_up(rt);
}
int query(int l,int r,int rt,int a,int b){
if(a<=l&&b>=r) return sum[rt];
push_down(rt,r-l+1);
int mid=l+r>>1,ans=0;
if(a<=mid) ans+=query(l,mid,rt<<1,a,b);
if(b>mid) ans+=query(mid+1,r,rt<<1|1,a,b);
return ans;
}
void updates(int x,int y,int k){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(d[fx]<d[fy]){
swap(x,y);
swap(fx,fy);
}
update(1,n,1,id[fx],id[x],k);
x=f[fx];fx=top[x];
}
if(id[x]>id[y]) swap(x,y);
update(1,n,1,id[x],id[y],k);
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<n;i++){
int x,y;
scanf("%lld%lld",&x,&y);
x++;y++;
w[x].push_back(y);
f[y]=x;
}
dfs1(1);
dfs2(1,1);
scanf("%lld",&q);
while(q--){
char c[1];
scanf("%s",c);
if(c[0]=='A'){
int u,v,d;
scanf("%lld%lld%lld",&u,&v,&d);
u++;v++;
updates(u,v,d);
}else{
int u;
scanf("%lld",&u);
u++;
printf("%lld\n",query(1,n,1,id[u],id[u]+size[u]-1));
}
}
return 0;
}