[SHOI2012]魔法树

原题链接:https://www.luogu.org/problemnew/show/P3833

题目背景

SHOI2012 D2T3

题目描述

Harry Potter 新学了一种魔法:可以让改变树上的果子个数。满心欢喜的他找到了一个巨大的果树,来试验他的新法术。

这棵果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u],保证有fa[u] < u。初始时,这棵果树上的果子都被 Dumbledore 用魔法清除掉了,所以这个果树的每个节点上都没有果子(即0个果子)。

不幸的是,Harry 的法术学得不到位,只能对树上一段路径的节点上的果子个数统一增加一定的数量。也就是说,Harry 的魔法可以这样描述:

Add u v d

表示将点u和v之间的路径上的所有节点的果子个数都加上d。

接下来,为了方便检验 Harry 的魔法是否成功,你需要告诉他在释放魔法的过程中的一些有关果树的信息:

Query u

表示当前果树中,以点u为根的子树中,总共有多少个果子?

输入输出格式

输入格式:

 

第一行一个正整数N (1 ≤ N ≤ 100000),表示果树的节点总数,节点以0,1,…,N − 1标号,0一定代表根节点。

接下来N − 1行,每行两个整数a,b (0 ≤ a < b < N),表示a是b的父亲。

接下来是一个正整数Q(1 ≤ ? ≤ 100000),表示共有Q次操作。

后面跟着Q行,每行是以下两种中的一种:

  1. A u v d,表示将u到v的路径上的所有节点的果子数加上d;0 ≤ u,v <N,0 < d < 100000

  2. Q u,表示询问以u为根的子树中的总果子数,注意是包括u本身的。

 

输出格式:

 

对于所有的Query操作,依次输出询问的答案,每行一个。答案可能会超过2^32 ,但不会超过10^15 。

 

输入输出样例

输入样例
4
0 1
1 2
2 3
4
A 1 3 1
Q 0
Q 1
Q 2
输出样例
3
3 2

树剖裸题.....记得开long long....

  1 #include <cstdio>
  2 #include <iostream>
  3 #define ll long long
  4 using namespace std;
  5 const int N=1500000+10;
  6 int v[N*2],nxt[N*2],first[N],cnt;
  7 int pos[N],dep[N],fa[N],top[N],siz[N],son[N],sz;
  8 int n,m;
  9 struct seg{
 10     int l,r;
 11     ll s,t;
 12 }tr[N*4];
 13 
 14 void read(int &x){
 15     x=0;int f=1;char c=getchar();
 16     while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
 17     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
 18     x*=f;
 19 }
 20 
 21 void add(int a,int b){
 22     v[++cnt]=b;
 23     nxt[cnt]=first[a];
 24     first[a]=cnt;
 25 }
 26 
 27 void dfs1(int x){
 28     siz[x]=1;
 29     for(int i=first[x];i;i=nxt[i]){
 30         if(fa[x]==v[i]) continue;
 31         dep[v[i]]=dep[x]+1;
 32         fa[v[i]]=x;
 33         dfs1(v[i]);
 34         siz[x]+=siz[v[i]];
 35         if(siz[v[i]]>siz[son[x]]) son[x]=v[i];
 36     }
 37 }
 38 
 39 void dfs2(int x,int y){
 40     pos[x]=++sz;top[x]=y;
 41     int k=son[x];
 42     if(!k) return ;
 43     dfs2(k,y);
 44     for(int i=first[x];i;i=nxt[i]) if(dep[v[i]]>dep[x]&&k!=v[i]) dfs2(v[i],v[i]); 
 45 }
 46 
 47 void build(int k,int s,int t){
 48     tr[k].l=s;tr[k].r=t;
 49     if(s==t) return ;
 50     int mid=(s+t)/2;
 51     build(k*2,s,mid);build(k*2+1,mid+1,t); 
 52 }
 53 
 54 void push(int k){
 55     int x=tr[k].r-tr[k].l+1;
 56     tr[k*2].t+=tr[k].t;
 57     tr[k*2+1].t+=tr[k].t;
 58     tr[k*2].s+=1ll*tr[k].t*(x-(x/2));
 59     tr[k*2+1].s+=1ll*tr[k].t*(x/2);
 60     tr[k].t=0;
 61 }
 62 
 63 void ud(int k,int s,int t,ll v){
 64     int l=tr[k].l,r=tr[k].r;
 65     if(s==l&&t==r){
 66         tr[k].t+=v;
 67         tr[k].s+=1ll*v*(r-l+1);
 68         return ;
 69     }
 70     if(tr[k].t) push(k);
 71     int mid=(l+r)/2;
 72     if(s>mid) ud(k*2+1,s,t,v);
 73     else if(t<=mid) ud(k*2,s,t,v);
 74     else {
 75         ud(k*2,s,mid,v);
 76         ud(k*2+1,mid+1,t,v);
 77     }
 78     tr[k].s=tr[k*2].s+tr[k*2+1].s;
 79 }
 80 
 81 void solud(int x,int y,ll v){
 82     while(top[x]!=top[y]){
 83         if(dep[top[x]]<dep[top[y]]) swap(x,y);
 84         ud(1,pos[top[x]],pos[x],v);
 85         x=fa[top[x]];
 86     }
 87     if(pos[x]>pos[y]) swap(x,y);
 88     ud(1,pos[x],pos[y],v);
 89 }
 90 
 91 ll qy(int k,int s,int t){
 92     int l=tr[k].l,r=tr[k].r;
 93     if(s==l&&t==r) return tr[k].s;
 94     if(tr[k].t) push(k);
 95     int mid=(l+r)/2;
 96     if(s>mid) return qy(k*2+1,s,t);
 97     else if(t<=mid) return qy(k*2,s,t);
 98     else return qy(k*2,s,mid)+qy(k*2+1,mid+1,t);
 99 }
100 
101 int main(){
102     read(n);
103     for(int i=1;i<n;i++){
104         int x,y;
105         read(x);read(y);
106         add(x+1,y+1);add(y+1,x+1);
107     }
108     dfs1(1);dfs2(1,1);
109     build(1,1,n);
110     int q;read(q);
111     for(int i=1;i<=q;i++){
112         char c[10];
113         int x,y;
114         ll z;
115         scanf("%s",c);read(x);++x;
116         if(c[0]=='Q') printf("%lld\n",qy(1,pos[x],pos[x]+siz[x]-1));
117         else{
118             read(y);scanf("%lld",&z);++y;
119             solud(x,y,z);
120         }
121     }
122     return 0;
123 }
View Code

 

posted @ 2018-03-24 17:13  lyf2  阅读(248)  评论(0编辑  收藏  举报