洛谷P3833 [SHOI2012]魔法树 (树链剖分)
题目链接:
https://www.luogu.com.cn/problem/P3833
思路:
树剖板子题
代码:
#include <bits/stdc++.h> #define ls node<<1,l,mid #define rs node<<1|1,mid+1,r using namespace std; const int MAXN=1e5+5; typedef long long ll; ll n; int head[MAXN],tot; struct node { int to,nxt; }e[MAXN<<1]; void add(int x,int y) { e[tot].to=y,e[tot].nxt=head[x],head[x]=tot++; } void add_edge(int x,int y) { add(x,y);add(y,x); } int dep[MAXN],f[MAXN],sz[MAXN],son[MAXN]; void dfs(int u,int fa) { dep[u]=dep[fa]+1;f[u]=fa;sz[u]=1; for(int i=head[u];~i;i=e[i].nxt) { int v=e[i].to; if(v!=fa) { dfs(v,u); sz[u]+=sz[v]; if(sz[v]>sz[son[u]]) son[u]=v; } } } int id[MAXN],top[MAXN],cnt; void dfs2(int u,int t) { top[u]=t;id[u]=++cnt; if(son[u]) dfs2(son[u],t); for(int i=head[u];~i;i=e[i].nxt) { int v=e[i].to; if(v!=f[u]&&v!=son[u]) dfs2(v,v); } } ll tree[MAXN<<2],lazy[MAXN<<2]; void push_up(int node) { tree[node]=tree[node<<1]+tree[node<<1|1]; } void build(int node,int l,int r) { if(l==r)return; int mid=(l+r)>>1; build(ls);build(rs); push_up(node); } void push_down(int node,int l,int r,int mid) { if(lazy[node]) { tree[node<<1]+=(mid-l+1)*lazy[node]; tree[node<<1|1]+=(r-mid)*lazy[node]; lazy[node<<1]+=lazy[node]; lazy[node<<1|1]+=lazy[node]; lazy[node]=0; } } void update(int node,int l,int r,int x,int y,int k) { if(l>=x&&r<=y) { tree[node]+=(r-l+1)*k;lazy[node]+=k;return; } int mid=(l+r)>>1; push_down(node,l,r,mid); if(x<=mid) update(ls,x,y,k); if(y>mid) update(rs,x,y,k); push_up(node); } ll query(int node,int l,int r,int x,int y) { if(l>=x&&r<=y)return tree[node]; ll ans=0; int mid=(l+r)>>1; push_down(node,l,r,mid); if(x<=mid) ans+=query(ls,x,y); if(y>mid) ans+=query(rs,x,y); return ans; } void tree_update(int x,int y,int z) { int fx=top[x],fy=top[y]; while(fx!=fy) { if(dep[fx]<dep[fy])swap(x,y),swap(fx,fy); update(1,1,cnt,id[fx],id[x],z); x=f[fx],fx=top[x]; } if(id[x]>id[y])swap(x,y); update(1,1,cnt,id[x],id[y],z); } int main() { scanf("%lld",&n); memset(head,-1,sizeof(head)); for(int i=1;i<n;i++) { ll x,y;scanf("%lld%lld",&x,&y); add_edge(x,y); } dfs(0,0);dfs2(0,0); build(1,1,n); int q;scanf("%d",&q); while(q--) { char str[2]; scanf("%s",str); if(str[0]=='A') { ll x,y,z;scanf("%lld%lld%lld",&x,&y,&z);tree_update(x,y,z); } else { ll x;scanf("%lld",&x);printf("%lld\n",query(1,1,n,id[x],id[x]+sz[x]-1)); } } return 0; }