P3833 [SHOI2012]魔法树
Posted qyj060604
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
以上是关于P3833 [SHOI2012]魔法树的主要内容,如果未能解决你的问题,请参考以下文章