# DFS序+线段树(bzoj 4034)

• 操作1：也就是将某两个点+a；
• 操作2：区间更新
• 操作3：查询起始区间到某点的和

  1 #include <cstdio>
2 #include <cstring>
3 #include <cctype>
4 #include <cmath>
5 #include <set>
6 #include <map>
7 #include <list>
8 #include <queue>
9 #include <deque>
10 #include <stack>
11 #include <string>
12 #include <vector>
13 #include <iostream>
14 #include <algorithm>
15 #include <stdlib.h>
16 #include <time.h>
17 using namespace std;
18 typedef long long LL;
19 const int INF=2e9+1e8;
20
21 const int MOD=1e9+7;
22 const double eps=0.0000000001;
23 void fre()
24 {
25     freopen("test.in","r",stdin);
26     freopen("test.out","w",stdout);
27 }
28 #define MSET(a,b) memset(a,b,sizeof(a))
29
30 const int maxn=1e6+10;
31 void zpsb(int x)
32 {
33     if(x>=0&&x<maxn) return ;
34     while(1);
35 }
36 struct Edge
37 {
38     int t,next;
39 }edge[maxn];
40 int sz,first[maxn],Treeval[maxn];
42 {
43     edge[sz].t=t,edge[sz].next=first[s];
44     first[s]=sz++;
45 }
46 int in[maxn],out[maxn];
47 int reid[maxn],io[maxn],tot;
48 void dfs(int x,int pre)
49 {
50     reid[in[x]=tot]=Treeval[x];
51     io[tot++]=1;
52     for(int i=first[x];i!=-1;i=edge[i].next)
53     {
54         int t=edge[i].t;
55         if(t==pre) continue;
56         dfs(t,x);
57     }
58     reid[out[x]=tot]=-Treeval[x];
59     io[tot++]=-1;
60 }
61
62
63 struct SegTree
64 {
65     struct Node
66     {
67         int l,r,flag;
68         LL lazy,sum;
69     }T[maxn*4];
70     void build(int i,int l,int r)
71     {
72         T[i].l=l,T[i].r=r;
73         T[i].lazy=T[i].flag=0;
74         if(l==r)
75         {
76             T[i].sum=reid[r];
77             T[i].flag=io[r];
78             return ;
79         }
80         int mid=(l+r)>>1;
81         build(i<<1,l,mid),build(i<<1|1,mid+1,r);
82         T[i].sum=T[i<<1].sum+T[i<<1|1].sum;
83         T[i].flag=T[i<<1].flag+T[i<<1|1].flag;
84     }
85     void pushdown(int i)
86     {
87         if(T[i].lazy)
88         {
89             T[i<<1].sum+=T[i].lazy*T[i<<1].flag;
90             T[i<<1|1].sum+=T[i].lazy*T[i<<1|1].flag;
91             T[i<<1].lazy+=T[i].lazy,T[i<<1|1].lazy+=T[i].lazy;
92             T[i].lazy=0;
93         }
94     }
95     void update(int i,int l,int r,LL k)
96     {
97         zpsb(i);
98         if(T[i].l==l&&T[i].r==r)
99         {
100             T[i].sum+=T[i].flag*k;
101             T[i].lazy+=k;
102             return ;
103         }
104         pushdown(i);
105         int mid=(T[i].l+T[i].r)>>1;
106         if(r<=mid) update(i<<1,l,r,k);
107         else if(l>mid) update(i<<1|1,l,r,k);
108         else update(i<<1,l,mid,k),update(i<<1|1,mid+1,r,k);
109         T[i].sum=T[i<<1].sum+T[i<<1|1].sum;
110     }
111     LL query(int i,int l,int r)
112     {
113         if(T[i].l==l&&T[i].r==r) return T[i].sum;
114         pushdown(i);
115         int mid=(T[i].l+T[i].r)>>1;
116         if(r<=mid) return query(i<<1,l,r);
117         else if(l>mid) return query(i<<1|1,l,r);
118         else return query(i<<1,l,mid)+query(i<<1|1,mid+1,r);
119     }
120 }wa;
121 int main()
122 {
123     int n,m;
124     MSET(first,-1);
125     sz=0;
126     scanf("%d%d",&n,&m);
127     for(int i=1;i<=n;i++)
128         scanf("%d",&Treeval[i]);
129     for(int i=2;i<=n;i++)
130     {
131         int x,y;
132         scanf("%d%d",&x,&y);
135     }
136     tot=1;
137     dfs(1,1);
138     // for(int i=1;i<=n;i++)
139     // {
140     //     printf("x=%d %d %d\n",i,in[i],out[i]);
141     // }
142     // for(int i=1;i<=2*n;i++)
143     // {
144     //     printf("id=%d val=%d\n",i,reid[i]);
145     // }
146     wa.build(1,1,2*n);
147     while(m--)
148     {
149         int opt;
150         scanf("%d",&opt);
151         if(opt==1)
152         {
153             int x,a;
154             scanf("%d%d",&x,&a);
155             wa.update(1,in[x],in[x],(LL)a);
156             wa.update(1,out[x],out[x],(LL)a);
157         }
158         else if(opt==2)
159         {
160             int x,a;
161             scanf("%d%d",&x,&a);
162             wa.update(1,in[x],out[x],(LL)a);
163         }
164         else
165         {
166             int x;
167             scanf("%d",&x);
168             printf("%lld\n",wa.query(1,1,in[x]));
169         }
170     }
171 }
172
173
174 /**************************************************/
179 /**************************************************/