P3833 [SHOI2012]魔法树
P3833 [SHOI2012]魔法树
丢人现场:线段树传标记打挂
以后LZT一定+=!
正经:这是一道裸的树剖
没有可说的
代码:
#include<bits/stdc++.h> using namespace std; const int N=100005; #define il inline typedef long long ll; int n,m; int fa[N]; int dep[N]; int size[N]={0}; int son[N]={0}; int dfn[N]; int indexy=0; int rk[N]; int top[N]; int hed[N],tal[N<<1],nxt[N<<1],cnt=0; struct Sugment_Tree{ ll t[N<<2]; ll LZT[N<<2]; #define mid (l+r)/2 il void push_up(int num){ t[num]=t[num<<1]+t[num<<1|1]; } Sugment_Tree(){memset(LZT,0,sizeof(LZT));} il void push_down(int l,int r,int num){ if(LZT[num]==0) return; LZT[num<<1]+=LZT[num]; LZT[num<<1|1]+=LZT[num]; t[num<<1]+=(ll)(mid-l+1)*LZT[num]; t[num<<1|1]+=(ll)(r-(mid+1)+1)*LZT[num]; LZT[num]=0; } il void build(int l,int r,int num){ if(l==r){ t[num]=0; LZT[num]=0; return; } build(l,mid,num<<1);build(mid+1,r,num<<1|1); push_up(num); } il void upt(int l,int r,int num,int L,int R,ll SUM){ //cout<<l<<"&@*& "<<r <<" "<<num<<" "<<L<<" "<<R<<" "<<SUM<<endl; if(l>R||r<L) return; if(l>=L&&r<=R){ t[num]+=(ll)(r-l+1)*SUM; LZT[num]+=SUM; return; } push_down(l,r,num); upt(l,mid,num<<1,L,R,SUM); upt(mid+1,r,num<<1|1,L,R,SUM); push_up(num); } il ll ask(int l,int r,int num,int L,int R){ if(l>R||r<L) return 0ll; if(l>=L&&r<=R){ return t[num]; } push_down(l,r,num); return ask(l,mid,num<<1,L,R)+ask(mid+1,r,num<<1|1,L,R); } }T; il void cgn(int x,int y,ll SUM){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); // cout<<dfn[top[x]]<<" &@$&$ "<<dfn[x]<<endl; T.upt(1,n,1,dfn[top[x]],dfn[x],SUM); x=fa[top[x]]; } if(dep[x]<dep[y]) swap(x,y); //cout<<dfn[y]<<" &@$&$ "<<dfn[x]<<endl; T.upt(1,n,1,dfn[y],dfn[x],SUM); } il void addege(int x,int y){ cnt++; tal[cnt]=y; nxt[cnt]=hed[x]; hed[x]=cnt; } il void dfs1(int u){ size[u]=1; for(int i=hed[u];i;i=nxt[i]){ int v=tal[i]; if(v==fa[u]) continue; dep[v]=dep[u]+1; dfs1(v); size[u]+=size[v]; if(size[v]>size[son[u]]) son[u]=v; } } il void dfs2(int u,int tp){ indexy++; dfn[u]=indexy; rk[dfn[u]]=u; top[u]=tp; if(!son[u]) return; dfs2(son[u],tp); for(int i=hed[u];i;i=nxt[i]){ int v=tal[i]; if(v==fa[u]||v==son[u]) continue; dfs2(v,v); } } int main(){ scanf("%d",&n); for(int i=1;i<n;i++){ int x,y; scanf("%d%d",&x,&y); x++,y++; fa[y]=x; addege(x,y); addege(y,x); } dep[1]=1; dfs1(1);//两个dfs预处理 dfs2(1,1); //for(int i=1;i<=n;i++) cout<<son[i]<<" "; // cout<<endl; T.build(1,n,1); scanf("%d",&m); while(m--){ char c[10]; scanf("%s",c); if(c[0]=='A'){ int x,y; ll val; scanf("%d%d%lld",&x,&y,&val); x++,y++; cgn(x,y,val); } else{ int u; scanf("%d",&u); u++; //cout<<dfn[u]<<" &*%&&$* "<<dfn[u]+size[u]-1<<endl; printf("%lld\n",T.ask(1,n,1,dfn[u],dfn[u]+size[u]-1)); } } return 0; }