1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #include <cmath>
6 #include <vector>
7 #include <queue>
8 #include <stack>
9 using namespace std;
10 const int maxn=200000+50;
11
12 int n,m,ans,tot,cnt,h[maxn],g[maxn];
13
14 struct node
15 {
16 int b,next;
17 };
18 node table[maxn];
19
20 struct nodee
21 {
22 vector<int> son;
23 int s,size,en,id,d,weight,w,f,top;
24 };
25 nodee tree[maxn];
26
27 struct nodeee
28 {
29 int l,r;
30 long long w,add;
31 };
32 nodeee treex[maxn<<2];
33
34 void add(int x,int y)
35 {
36 table[++cnt].b=y;
37 table[cnt].next=h[x];
38 h[x]=cnt;
39 }
40
41 void dfs1(int x,int fa)
42 {
43 tree[x].weight=tree[x].size=1;
44 tree[x].d=tree[fa].d+1;
45 tree[x].f=fa;
46 for (int i=h[x]; i; i=table[i].next)
47 {
48 int t=table[i].b;
49 if (t!=fa)
50 {
51 tree[x].son.push_back(t);
52 dfs1(t,x);
53 if (tree[x].weight<tree[t].size+1)
54 {
55 tree[x].s=t;
56 tree[x].weight=tree[t].size+1;
57 }
58 tree[x].size+=tree[t].size;;
59 }
60 }
61 }
62
63 void dfs2(int x,int fa)
64 {
65 tree[x].id=++cnt;
66 g[cnt]=x;
67 tree[x].top=fa;
68 if (tree[x].s)
69 dfs2(tree[x].s,fa);
70 for (int i=0; i<tree[x].son.size(); ++i)
71 if (tree[x].son[i]!=tree[x].s)
72 {
73 dfs2(tree[x].son[i],tree[x].son[i]);
74 }
75 tree[x].en=cnt;
76 }
77
78 void pushup(int tr)
79 {
80 treex[tr].w=treex[tr<<1].w+treex[tr<<1|1].w;
81 }
82
83 void pushdown(int lsum,int rsum,int tr)
84 {
85 if (!treex[tr].add)
86 {
87 return;
88 }
89 treex[tr<<1].w+=(long long) (lsum)*treex[tr].add;
90 treex[tr<<1|1].w+=(long long) (rsum)*treex[tr].add;
91 treex[tr<<1].add+=treex[tr].add;
92 treex[tr<<1|1].add+=treex[tr].add;
93 treex[tr].add=0;
94 }
95
96 void build(int l,int r,int tr)
97 {
98 treex[tr].l=l;
99 treex[tr].r=r;
100 if (l==r)
101 {
102 treex[tr].w=tree[g[l]].w;
103 return;
104 }
105 int mid=(l+r)>>1;
106 build(l,mid,tr<<1);
107 build(mid+1,r,tr<<1|1);
108 pushup(tr);
109 }
110
111 void update(int l,int r,int tr,int ql,int qr,int qw)
112 {
113 if (l>=ql && r<=qr)
114 {
115 treex[tr].add+=qw;
116 treex[tr].w+=(long long)qw*(long long)(r-l+1);
117 return;
118 }
119 int mid=(l+r)>>1;
120 pushdown(mid-l+1,r-mid,tr);
121 if (mid>=ql)
122 update(l,mid,tr<<1,ql,qr,qw);
123 if (mid<qr)
124 update(mid+1,r,tr<<1|1,ql,qr,qw);
125 pushup(tr);
126 return;
127 }
128
129 long long query(int l,int r,int tr,int ql,int qr)
130 {
131 if (l>=ql && r<=qr)
132 {
133 return treex[tr].w;
134 }
135 int mid=(l+r)>>1;
136 pushdown(mid-l+1,r-mid,tr);
137 long long tot=0;
138 if (mid>=ql)
139 tot+=query(l,mid,tr<<1,ql,qr);
140 if (mid<qr)
141 tot+=query(mid+1,r,tr<<1|1,ql,qr);
142 return tot;
143 }
144
145 void ask(int q)
146 {
147 long long tot=0;
148 while (tree[q].top!=1)
149 {
150 tot+=query(1,n,1,tree[tree[q].top].id,tree[q].id);
151 q=tree[tree[q].top].f;
152 }
153 tot+=query(1,n,1,tree[1].id,tree[q].id);
154 printf("%lld\n",tot);
155 }
156
157 int main()
158 {
159 scanf("%d%d",&n,&m);
160 for (int i=1; i<=n; ++i)
161 scanf("%d",&tree[i].w);
162 for (int i=1,q1,q2; i<n; ++i)
163 {
164 scanf("%d%d",&q1,&q2);
165 add(q1,q2);
166 add(q2,q1);
167 }
168 dfs1(1,1);
169 cnt=0;
170 dfs2(1,1);
171 build(1,n,1);
172 for (int i=1,q1,q2,q3; i<=m; ++i)
173 {
174 scanf("%d%d",&q1,&q2);
175 if (q1==1)
176 {
177 scanf("%d",&q3);
178 update(1,n,1,tree[q2].id,tree[q2].id,q3);
179 }
180 if (q1==2)
181 {
182 scanf("%d",&q3);
183 update(1,n,1,tree[q2].id,tree[q2].en,q3);
184 }
185 if (q1==3)
186 ask(q2);
187 }
188 return 0;
189 }