洛谷 3833 SHOI 2012 魔法树
Posted Driver_Lao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 3833 SHOI 2012 魔法树相关的知识,希望对你有一定的参考价值。
【题解】
树链剖分模板题。。
#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; }
以上是关于洛谷 3833 SHOI 2012 魔法树的主要内容,如果未能解决你的问题,请参考以下文章