B20J_2836_魔法树_树链剖分+线段树
题意:
果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u]。初始时,这个果树的每个节点上都没有果子(即0个果子)。
Add u v d
表示将点u和v之间的路径上的所有节点的果子个数都加上d。
Query u
表示当前果树中,以点u为根的子树中,总共有多少个果子?
分析:模板题。记录一下x结点的子孙中最后一次出现的位置。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 #define N 100010 6 #define lson pos<<1 7 #define rson pos<<1|1 8 #define LL long long 9 int head[N],to[N<<1],nxt[N<<1],cnt,n,tot,m; 10 int dep[N],siz[N],fa[N],son[N],idx[N],top[N],sec[N]; 11 LL t[N<<2],lz[N<<2]; 12 char ch[10]; 13 inline void read(int &x) 14 { 15 int f=1;x=0;char s=getchar(); 16 while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();} 17 while(s>=‘0‘&&s<=‘9‘){x=(x<<3)+(x<<1)+s-‘0‘;s=getchar();} 18 x*=f; 19 } 20 inline void add(int u,int v) 21 { 22 to[++cnt]=v; 23 nxt[cnt]=head[u]; 24 head[u]=cnt; 25 } 26 inline void dfs1(int x,int y) 27 { 28 dep[x]=dep[y]+1; 29 fa[x]=y; 30 siz[x]=1; 31 for(int i=head[x];i;i=nxt[i]) 32 { 33 if(to[i]!=y) 34 { 35 dfs1(to[i],x); 36 siz[to[i]]+=siz[x]; 37 if(siz[to[i]]>siz[son[x]]) 38 { 39 son[x]=to[i]; 40 } 41 } 42 } 43 } 44 inline void dfs2(int x,int t) 45 { 46 top[x]=t; 47 idx[x]=++tot; 48 if(son[x])dfs2(son[x],t); 49 for(int i=head[x];i;i=nxt[i]) 50 { 51 if(to[i]!=fa[x]&&to[i]!=son[x]) 52 { 53 dfs2(to[i],to[i]); 54 } 55 } 56 sec[x]=tot; 57 } 58 inline void pud(int l,int r,int pos,int c) 59 { 60 t[pos]+=(r-l+1)*c; 61 lz[pos]+=c; 62 } 63 inline void up(int l,int r,int x,int y,int z,int pos) 64 { 65 if(x<=l&&y>=r) 66 { 67 t[pos]+=(r-l+1)*z; 68 lz[pos]+=z; 69 return ; 70 } 71 int mid=l+r>>1; 72 if(lz[pos]) 73 { 74 pud(l,mid,lson,lz[pos]); 75 pud(mid+1,r,rson,lz[pos]); 76 lz[pos]=0; 77 } 78 if(x<=mid)up(l,mid,x,y,z,lson); 79 if(y>mid)up(mid+1,r,x,y,z,rson); 80 t[pos]=t[lson]+t[rson]; 81 } 82 inline LL query(int l,int r,int x,int y,int pos) 83 { 84 if(x<=l&&y>=r) 85 { 86 return t[pos]; 87 } 88 int mid=l+r>>1; 89 if(lz[pos]) 90 { 91 pud(l,mid,lson,lz[pos]); 92 pud(mid+1,r,rson,lz[pos]); 93 lz[pos]=0; 94 } 95 LL re=0; 96 if(x<=mid)re+=query(l,mid,x,y,lson); 97 if(y>mid)re+=query(mid+1,r,x,y,rson); 98 return re; 99 } 100 int main() 101 { 102 read(n); 103 register int x,y,i,z; 104 for(i=1;i<n;++i) 105 { 106 read(x),read(y); 107 add(x+1,y+1); 108 add(y+1,x+1); 109 } 110 dfs1(1,0); 111 dfs2(1,1); 112 read(m); 113 while(m--) 114 { 115 scanf("%s",ch); 116 if(ch[0]==‘A‘) 117 { 118 read(x),read(y),read(z); 119 x++,y++; 120 while(top[x]!=top[y]) 121 { 122 if(dep[top[x]]>dep[top[y]])swap(x,y); 123 up(1,n,idx[top[y]],idx[y],z,1); 124 y=fa[top[y]]; 125 } 126 if(dep[x]<dep[y])swap(x,y); 127 up(1,n,idx[y],idx[x],z,1); 128 } 129 else 130 { 131 read(x); 132 x++; 133 printf("%lld\n",query(1,n,idx[x],sec[x],1)); 134 } 135 } 136 }