[BZOJ]2836: 魔法树
题解:树链剖分裸题
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=3e5+10; const double eps=1e-8; #define ll long long using namespace std; struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e; void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;} ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } int num[MAXN],dep[MAXN],fa[MAXN],son[MAXN],n,q; void dfs1(int x,int pre,int deep){ fa[x]=pre;dep[x]=deep+1;num[x]=1; link(x){ if(j->t==pre)continue; dfs1(j->t,x,deep+1); num[x]+=num[j->t]; if(son[x]==-1||num[son[x]]<num[j->t])son[x]=j->t; } } ll flag[MAXN<<2],sum[MAXN<<2]; void push(int rt,int l,int r){ if(flag[rt]){ int mid=(l+r)>>1; flag[rt<<1]+=flag[rt];flag[rt<<1|1]+=flag[rt]; sum[rt<<1]+=1ll*(mid-l+1)*flag[rt]; sum[rt<<1|1]+=1ll*(r-mid)*flag[rt]; flag[rt]=0; } } void update(int rt,int l,int r,int ql,int qr,int t){ if(ql<=l&&r<=qr){ sum[rt]+=1ll*(r-l+1)*t;flag[rt]+=t; return ; } int mid=(l+r)>>1; push(rt,l,r); if(ql<=mid)update(rt<<1,l,mid,ql,qr,t); if(qr>mid)update(rt<<1|1,mid+1,r,ql,qr,t); sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } ll ans; void query(int rt,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr){ans+=sum[rt];return ;} int mid=(l+r)>>1; push(rt,l,r); if(ql<=mid)query(rt<<1,l,mid,ql,qr); if(qr>mid)query(rt<<1|1,mid+1,r,ql,qr); sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } int tp[MAXN],p[MAXN],cnt; void dfs2(int x,int td){ tp[x]=td;p[x]=++cnt; if(son[x]!=-1)dfs2(son[x],td); link(x){ if(j->t==fa[x]||son[x]==j->t)continue; dfs2(j->t,j->t); } } void Add(int u,int v,int t){ int uu=tp[u];int vv=tp[v]; while(uu!=vv){ if(dep[uu]<dep[vv])swap(uu,vv),swap(u,v); update(1,1,n,p[uu],p[u],t); u=fa[uu];uu=tp[u]; } if(dep[u]>dep[v])swap(u,v); update(1,1,n,p[u],p[v],t); } ll Query(int u){ ans=0;query(1,1,n,p[u],p[u]+num[u]-1); return ans; } int main(){ n=read(); int u,v,t; inc(i,1,n)son[i]=-1; inc(i,2,n)u=read()+1,v=read()+1,add(u,v),add(v,u); dfs1(1,0,0);dfs2(1,1); q=read(); char str[11]; while(q--){ scanf("%s",str);u=read()+1; if(str[0]=='Q')printf("%lld\n",Query(u)); else v=read()+1,t=read(),Add(u,v,t); } return 0; }
2836: 魔法树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 625 Solved: 245
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
4
0 1
1 2
2 3
4
Add 1 3 1
Query 0
Query 1
Query 2
0 1
1 2
2 3
4
Add 1 3 1
Query 0
Query 1
Query 2
Sample Output
3
3
2
3
2