BZOJ2836:[SHOI2012]魔法树(树链剖分)

Description

Input

Output

Sample Input

4
0 1
1 2
2 3
4
Add 1 3 1
Query 0
Query 1
Query 2

Sample Output

3
3
2

Solution

退役选手打打板子休闲一下QAQ

居然能1A真是不可思议

Code

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<algorithm>
  6 #define N (100000+1000)
  7 using namespace std;
  8 
  9 struct Edge{int to,next;}edge[N<<1];
 10 struct Node{long long val,add;}Segt[N<<2];
 11 
 12 int Depth[N],Father[N],Size[N];
 13 int T_NUM[N],Top[N],Son[N];
 14 int head[N],num_edge;
 15 int x,y,k,n,m,cnt;
 16 char opt[3];
 17 
 18 void add(int u,int v)
 19 {
 20     edge[++num_edge].to=v;
 21     edge[num_edge].next=head[u];
 22     head[u]=num_edge;
 23 }
 24 
 25 void Dfs1(int x)
 26 {
 27     Depth[x]=Depth[Father[x]]+1;
 28     Size[x]=1;
 29     for (int i=head[x]; i; i=edge[i].next)
 30         if (edge[i].to!=Father[x])
 31         {
 32             Father[edge[i].to]=x;
 33             Dfs1(edge[i].to);
 34             Size[x]+=Size[edge[i].to];
 35             if (!Son[x] || Size[edge[i].to]>Son[x])
 36                 Son[x]=edge[i].to;
 37         }
 38 }
 39 
 40 void Dfs2(int x,int top)
 41 {
 42     Top[x]=top;
 43     T_NUM[x]=++cnt;
 44     if (Son[x]) Dfs2(Son[x],top);
 45     for (int i=head[x]; i; i=edge[i].next)
 46         if (edge[i].to!=Father[x] && edge[i].to!=Son[x])
 47             Dfs2(edge[i].to,edge[i].to);
 48 }
 49 
 50 void Pushdown(int now,int l,int r)
 51 {
 52     if (Segt[now].add)
 53     {
 54         Segt[now<<1].add+=Segt[now].add;
 55         Segt[now<<1|1].add+=Segt[now].add;
 56         int mid=(l+r)>>1;
 57         Segt[now<<1].val+=Segt[now].add*(mid-l+1);
 58         Segt[now<<1|1].val+=Segt[now].add*(r-mid);
 59         Segt[now].add=0;
 60     }
 61 }
 62 
 63 void Update(int now,int l,int r,int l1,int r1,int k)
 64 {
 65     if (r<l1 || l>r1) return;
 66     if (l1<=l && r<=r1)
 67     {
 68         Segt[now].val+=(long long)(r-l+1)*k;
 69         Segt[now].add+=k;
 70         return;
 71     }
 72     Pushdown(now,l,r);
 73     int mid=(l+r)>>1;
 74     Update(now<<1,l,mid,l1,r1,k);
 75     Update(now<<1|1,mid+1,r,l1,r1,k);
 76     Segt[now].val=Segt[now<<1].val+Segt[now<<1|1].val;
 77 }
 78 
 79 long long Query(int now,int l,int r,int l1,int r1)
 80 {
 81     if (l1<=l && r<=r1)
 82         return Segt[now].val;
 83     Pushdown(now,l,r);
 84     int mid=(l+r)>>1;
 85     if (r1<=mid) return Query(now<<1,l,mid,l1,r1);
 86     if (l1>=mid+1) return Query(now<<1|1,mid+1,r,l1,r1);
 87     return Query(now<<1,l,mid,l1,r1)+Query(now<<1|1,mid+1,r,l1,r1);
 88 }
 89 
 90 void Change(int x,int y,int k)
 91 {
 92     int fx=Top[x],fy=Top[y];
 93     while (fx!=fy)
 94     {
 95         if (Depth[fx]<Depth[fy])
 96             swap(x,y),swap(fx,fy);
 97         Update(1,1,n,T_NUM[fx],T_NUM[x],k);
 98         x=Father[fx],fx=Top[x];
 99     }
100     if (Depth[x]<Depth[y]) swap(x,y);
101     Update(1,1,n,T_NUM[y],T_NUM[x],k);
102 }
103 
104 int main()
105 {
106     scanf("%d",&n);
107     for (int i=1; i<=n-1; ++i)
108     {
109         scanf("%d%d",&x,&y);
110         x++; y++;
111         add(x,y); add(y,x);
112     }
113     Dfs1(1); Dfs2(1,1);
114     scanf("%d",&m);
115     for (int i=1; i<=m; ++i)
116     {
117         scanf("%s",opt);
118         if (opt[0]=='A')
119         {
120             scanf("%d%d%d",&x,&y,&k); x++; y++;
121             Change(x,y,k);
122         }
123         else
124         {
125             scanf("%d",&x); x++;
126             printf("%lld\n",Query(1,1,n,T_NUM[x],T_NUM[x]+Size[x]-1));
127         }
128     }
129 }
posted @ 2018-05-27 09:17  Refun  阅读(290)  评论(0编辑  收藏  举报