BZOJ 4034

考场上直接A掉了~啦啦啦~

传送门

正解是俩树状数组…但是太弱了不会啊…于是只能拿树链剖分搞了…

考场上敲了40min+ 各种数据拍+调了一个小时找了仨错出来最后顺利AC啦啦啦

HA考场上好像没几个人A…但是挂到BZOJ上以后就被各种艹翻…QAQ

考场上敲的代码↓ OwO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
program bzoj_4034;
var s:array[1..100000]of record fa,size,hev,l,r,w,bl,rk:longint; end;
seq,lst,top:array[1..100000]of longint;
l:array[1..200000]of record ed,pre:longint; end;
seg:array[1..200000]of record l,r,lc,rc:longint; plus,sum:int64; end;
n,m,i,a,b,tot,len,pcnt,cas:longint;
procedure link(a,b:longint);
begin
inc(tot);
l[tot].pre:=lst[a];
lst[a]:=tot;
l[tot].ed:=b;
end;
procedure dfs1(t:longint);
var k,max,p:longint;
begin
s[t].size:=1;
k:=lst[t];
s[t].hev:=0;
max:=0;
while k<>0 do
begin
if l[k].ed<>s[t].fa then
begin
s[l[k].ed].fa:=t;
dfs1(l[k].ed);
inc(s[t].size,s[l[k].ed].size);
if s[l[k].ed].size>max then
begin
max:=s[l[k].ed].size;
s[t].hev:=l[k].ed;
end;
end;
k:=l[k].pre;
end;
k:=lst[t];
while k<>0 do
begin
if l[k].ed<>s[t].fa then
begin
if l[k].ed=s[t].hev then
begin
s[t].bl:=s[l[k].ed].bl;
s[t].rk:=s[l[k].ed].rk+1;
end else
begin
p:=s[l[k].ed].bl;
top[p]:=l[k].ed;
end;
end;
k:=l[k].pre;
end;
if s[t].hev=0 then
begin
inc(pcnt);
s[t].bl:=pcnt;
s[t].rk:=1;
end;
end;
procedure dfs2(t:longint);
var k:longint;
begin
inc(len);
s[t].l:=len;
seq[len]:=s[t].w;
if s[t].hev<>0 then
begin
k:=lst[t];
while (k<>0)and(l[k].ed<>s[t].hev) do k:=l[k].pre;
dfs2(l[k].ed);
k:=lst[t];
while k<>0 do
begin
if (l[k].ed<>s[t].fa)and(l[k].ed<>s[t].hev) then dfs2(l[k].ed);
k:=l[k].pre;
end;
end;
s[t].r:=len;
end;
procedure pushdown(t:longint);
var l,r:longint;
begin
if seg[t].plus=0 then exit;
if seg[t].l=seg[t].r then
begin
seg[t].plus:=0;
exit;
end;
l:=seg[t].lc;
r:=seg[t].rc;
inc(seg[l].plus,seg[t].plus);
inc(seg[r].plus,seg[t].plus);
inc(seg[l].sum,seg[t].plus*int64(seg[l].r-seg[l].l+1));
inc(seg[r].sum,seg[t].plus*int64(seg[r].r-seg[r].l+1));
seg[t].plus:=0;
end;
procedure build(var t:longint;l,r:longint);
var mid:longint;
begin
inc(tot);
t:=tot;
seg[t].l:=l;
seg[t].r:=r;
seg[t].plus:=0;
if l=r then
begin
seg[t].sum:=seq[l];
seg[t].lc:=0;
seg[t].rc:=0;
exit;
end;
mid:=(l+r)>>1;
build(seg[t].lc,l,mid);
build(seg[t].rc,mid+1,r);
seg[t].sum:=seg[seg[t].lc].sum+seg[seg[t].rc].sum;
end;
procedure plus(t,l,r,d:longint);
var mid:longint;
begin
if seg[t].plus<>0 then pushdown(t);
if (l<=seg[t].l)and(r>=seg[t].r) then
begin
inc(seg[t].plus,d);
inc(seg[t].sum,seg[t].plus*int64(seg[t].r-seg[t].l+1));
pushdown(t);
exit;
end;
if seg[t].plus<>0 then pushdown(t);
mid:=(seg[t].l+seg[t].r)>>1;
if l<=mid then plus(seg[t].lc,l,r,d);
if r>mid then plus(seg[t].rc,l,r,d);
seg[t].sum:=seg[seg[t].lc].sum+seg[seg[t].rc].sum;
end;
function query(t,l,r:longint):int64;
var ans:int64;
mid:longint;
begin
if seg[t].plus<>0 then pushdown(t);
if (l<=seg[t].l)and(r>=seg[t].r) then exit(seg[t].sum);
ans:=0;
mid:=(seg[t].l+seg[t].r)>>1;
if l<=mid then inc(ans,query(seg[t].lc,l,r));
if r>mid then inc(ans,query(seg[t].rc,l,r));
exit(ans);
end;
procedure ask(t:longint);
var ans:int64;
begin
ans:=0;
while top[s[t].bl]<>1 do
begin
inc(ans,query(1,s[top[s[t].bl]].l,s[t].l));
t:=s[top[s[t].bl]].fa;
end;
inc(ans,query(1,s[1].l,s[t].l));
writeln(ans);
end;
begin
readln(n,m);
for i:=1 to n do read(s[i].w);
tot:=0;
for i:=1 to n-1 do
begin
readln(a,b);
link(a,b);
link(b,a);
end;
len:=0;
s[1].fa:=0;
pcnt:=0;
dfs1(1);
i:=s[1].bl;
top[i]:=1;
dfs2(1);
tot:=0;
build(i,1,n);
for i:=1 to m do
begin
read(cas);
case cas of
1:begin
readln(a,b);
plus(1,s[a].l,s[a].l,b);
end;
2:begin
readln(a,b);
plus(1,s[a].l,s[a].r,b);
end;
3:begin
readln(a);
ask(a);
end;
end;
end;
end.