B20J_2836_魔法树_树链剖分+线段树
题意:
果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u]。初始时,这个果树的每个节点上都没有果子(即0个果子)。
Add u v d
表示将点u和v之间的路径上的所有节点的果子个数都加上d。
Query u
表示当前果树中,以点u为根的子树中,总共有多少个果子?
分析:树链剖分+线段树模板题。记录一下x结点的子树中最后一次出现的位置即可。
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 100010 #define lson pos<<1 #define rson pos<<1|1 #define LL long long int head[N],to[N<<1],nxt[N<<1],cnt,n,tot,m; int dep[N],siz[N],fa[N],son[N],idx[N],top[N],sec[N]; LL t[N<<2],lz[N<<2]; char ch[10]; inline void read(int &x) { int f=1;x=0;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();} x*=f; } inline void add(int u,int v) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; } inline void dfs1(int x,int y) { dep[x]=dep[y]+1; fa[x]=y; siz[x]=1; for(int i=head[x];i;i=nxt[i]) { if(to[i]!=y) { dfs1(to[i],x); siz[to[i]]+=siz[x]; if(siz[to[i]]>siz[son[x]]) { son[x]=to[i]; } } } } inline void dfs2(int x,int t) { top[x]=t; idx[x]=++tot; if(son[x])dfs2(son[x],t); for(int i=head[x];i;i=nxt[i]) { if(to[i]!=fa[x]&&to[i]!=son[x]) { dfs2(to[i],to[i]); } } sec[x]=tot; } inline void pud(int l,int r,int pos,int c) { t[pos]+=(r-l+1)*c; lz[pos]+=c; } inline void up(int l,int r,int x,int y,int z,int pos) { if(x<=l&&y>=r) { t[pos]+=(r-l+1)*z; lz[pos]+=z; return ; } int mid=l+r>>1; if(lz[pos]) { pud(l,mid,lson,lz[pos]); pud(mid+1,r,rson,lz[pos]); lz[pos]=0; } if(x<=mid)up(l,mid,x,y,z,lson); if(y>mid)up(mid+1,r,x,y,z,rson); t[pos]=t[lson]+t[rson]; } inline LL query(int l,int r,int x,int y,int pos) { if(x<=l&&y>=r) { return t[pos]; } int mid=l+r>>1; if(lz[pos]) { pud(l,mid,lson,lz[pos]); pud(mid+1,r,rson,lz[pos]); lz[pos]=0; } LL re=0; if(x<=mid)re+=query(l,mid,x,y,lson); if(y>mid)re+=query(mid+1,r,x,y,rson); return re; } int main() { read(n); register int x,y,i,z; for(i=1;i<n;++i) { read(x),read(y); add(x+1,y+1); add(y+1,x+1); } dfs1(1,0); dfs2(1,1); read(m); while(m--) { scanf("%s",ch); if(ch[0]=='A') { read(x),read(y),read(z); x++,y++; while(top[x]!=top[y]) { if(dep[top[x]]>dep[top[y]])swap(x,y); up(1,n,idx[top[y]],idx[y],z,1); y=fa[top[y]]; } if(dep[x]<dep[y])swap(x,y); up(1,n,idx[y],idx[x],z,1); } else { read(x); x++; printf("%lld ",query(1,n,idx[x],sec[x],1)); } } }