1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 #define rint register int
6
7 int n, q, u, v, pow[100000];
8 int k[100000], a[100000], b[100000];
9 int begin[100000], end[100000];
10 int fa[100000][22], depth[100000];
11
12 char ch,B[1<<15],*S=B,*T=B,buf[1<<21],*O=buf,stk[40];
13 #define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
14 inline const int getint() //输入优化
15 {
16 char c = getc();
17 rint k = 1, r = 0;
18 for(; c < ‘0‘ || c > ‘9‘; c = getc())
19 if(c == ‘-‘) k = -1;
20 for(; c >= ‘0‘ && c <= ‘9‘; c = getc())
21 r = r * 10 + c - ‘0‘;
22 return k * r;
23 }
24
25 int lca(rint x, rint y) //找LCA
26 {
27 rint i;
28 if (depth[x] < depth[y])
29 x ^= y, y ^= x, x ^= y;
30 for (i = fa[x][21]; depth[x] > depth[y]; i--)
31 if (depth[fa[x][i]] >= depth[y]) x = fa[x][i];
32 if (x == y) return x;
33 for (i = fa[x][21]; i >= 0; i--)
34 if (fa[x][i] != fa[y][i])
35 x = fa[x][i], y = fa[y][i];
36 return fa[x][0];
37
38 }
39
40 /*********edges**********/
41 int ep[200000], et[200000];
42 int last[100000], en;
43
44 inline void addedge(rint f, rint t) //邻接表
45 {
46 en++;
47 ep[en] = last[f];
48 last[f] = en;
49 et[en] = t;
50 }
51
52 /*****Discretization*****/
53 int num[200000], count;
54
55 int lb(rint key) // lower_bound
56 {
57 rint l = 1, r = count, mid;
58 while (l < r)
59 {
60 mid = l + r >> 1;
61 if (num[mid] == key)
62 return mid;
63 if (num[mid] < key)
64 l = mid + 1;
65 else r = mid - 1;
66 }
67 return l;
68 }
69
70 void discretizate() //离散化
71 {
72 std::sort(num + 1, num + count + 1);
73 rint tmp = 0, i;
74 num[++count] = 1000000013;
75 for (i = 1; i <= count; i++)
76 {
77 if (num[i] != num[i + 1])
78 num[++tmp] = num[i];
79 }
80 count = tmp;
81 for (i = 1; i <= n; i++)
82 {
83 pow[i] = lb(pow[i]);
84 }
85 }
86
87 /********ZX-Tree*********/
88 int nls[10000000], nrs[10000000], nsum[10000000];
89
90 int ns, tmpos, tmdata;
91
92 void tmodify(int &t, rint left, rint right) //主席树上修改
93 {
94 if (t == 0)
95 {
96 nsum[t = ++ns] = 0;
97 }
98 if (left < right)
99 {
100 int mid = left + right >> 1;
101 if (tmpos <= mid) tmodify(nls[t], left, mid);
102 else tmodify(nrs[t], mid + 1, right);
103 nsum[t] += tmdata;
104 } else nsum[t] += tmdata;
105 }
106
107 /*******tree-array*******/
108 int root[100000], rts;
109
110 void modify(rint x, rint y, rint pos, rint data) //树状数组上修改一段区间
111 {
112 tmpos = pos, tmdata = data;
113 for (; x <= n; x += x & -x)
114 tmodify(root[x], 1, count);
115 tmdata = -data;
116 for (y++; y <= n; y += y & -y)
117 tmodify(root[y], 1, count);
118 }
119
120 int rs[4][30];
121
122 int init_rs(rint i, rint x) //用rs数组记录查询时需要用到的点
123 {
124 memset(rs[i], 0, sizeof (rs[i]));
125 int ret = 0;
126 for (; x > 0; x -= x & -x)
127 {
128 rs[i][++rs[i][0]] = root[x];
129 ret += nsum[root[x]];
130 }
131 return ret;
132 }
133
134 int query_rs() //查询每个点右儿子的大小
135 {
136 int ret = 0; rint i;
137 for (i = 1; i <= rs[0][0]; i++)
138 ret += nsum[nrs[rs[0][i]]];
139 for (i = 1; i <= rs[1][0]; i++)
140 ret += nsum[nrs[rs[1][i]]];
141 for (i = 1; i <= rs[2][0]; i++)
142 ret -= nsum[nrs[rs[2][i]]];
143 for (i = 1; i <= rs[3][0]; i++)
144 ret -= nsum[nrs[rs[3][i]]];
145 return ret;
146 }
147
148 void down(rint d) //将每个点变成它的左/右儿子
149 {
150 rint x, i;
151 for (x = 0; x < 4; x++)
152 for (i = 1; i <= rs[x][0]; i++)
153 rs[x][i] = d ? nrs[rs[x][i]] : nls[rs[x][i]];
154 }
155
156 int query(rint x, rint y, rint data) //查询
157 {
158 int s = 0, f = lca(x, y), mid;
159 s += init_rs(0, begin[x]);
160 s += init_rs(1, begin[y]);
161 s -= init_rs(2, begin[f]);
162 s -= init_rs(3, begin[fa[f][0]]);
163 if (s < data) return -1;
164 int left = 1, right = count;
165 while (left < right) //迭代
166 {
167 mid = left + right >> 1;
168 s = query_rs();
169 if (data > s)
170 {
171 down(0);
172 right = mid;
173 data -= s;
174 }
175 else
176 {
177 down(1);
178 left = mid + 1;
179 }
180 }
181 return num[left];
182 }
183
184 /**********dfs***********/
185 void DFS(rint x) //找出dfs序和求lca的rmq数组
186 {
187 rint i;
188 depth[x] = depth[fa[x][0]] + 1;
189 for (i = 0; fa[x][i]; fa[x][21] = ++i)
190 fa[x][i + 1] = fa[fa[x][i]][i];
191 begin[x] = ++rts;
192 root[begin[x]] = ++ns;
193 for (i = last[x]; i; i = ep[i])
194 if (begin[et[i]] == 0)
195 fa[et[i]][0] = x, DFS(et[i]);
196 end[x] = rts;
197 }
198
199 int main()
200 {
201 n = getint();
202 q = getint();
203 count = 0;
204 rint i, tmp;
205 for (i = 1; i <= n; i++)
206 num[++count] = pow[i] = getint();
207 for (i = 1; i < n; i++)
208 {
209 u = getint();
210 v = getint();
211 addedge(u, v);
212 addedge(v, u);
213 }
214 for (i = 1; i <= q; i++)
215 {
216 k[i] = getint();
217 a[i] = getint();
218 b[i] = getint();
219 if (k[i] == 0) num[++count] = b[i];
220 }
221 discretizate();
222 DFS(1);
223 for (i = 1; i <= n; i++)
224 {
225 modify(begin[i], end[i], pow[i], 1);
226 }
227 for (i = 1; i <= q; i++)
228 {
229 if (k[i])
230 {
231 tmp = query(a[i], b[i], k[i]);
232 if (tmp >= 0) printf("%d\n", tmp);
233 else printf("invalid request!\n");
234 }
235 else
236 {
237 modify(begin[a[i]], end[a[i]], pow[a[i]], -1);
238 pow[a[i]] = lb(b[i]);
239 modify(begin[a[i]], end[a[i]], pow[a[i]], 1);
240 }
241 }
242 }