1 /*
2 唐代韦庄
3 《菩萨蛮·劝君今夜须沈醉》
4 劝君今夜须沉醉,尊前莫话明朝事。珍重主人心,酒深情亦深。
5 须愁春漏短,莫诉金杯满。遇酒且呵呵,人生能几何!
6 */
7 #include <iostream>
8 #include <cstdio>
9 #include <algorithm>
10 #include <cstring>
11 #include <vector>
12 #include <utility>
13 #include <iomanip>
14 #include <string>
15 #include <cmath>
16 #include <queue>
17 #include <assert.h>
18 #include <map>
19 #include <ctime>
20 #include <cstdlib>
21 #include <stack>
22 #include <set>
23 #define LOCAL
24 const int INF = 0x7fffffff;
25 const int MAXN = 80000 + 10;
26 const int maxnode = 20000 * 2 + 200000 * 20;
27 const int MAXM = 1000000 + 10;
28 const int MAX = 100000000;
29 using namespace std;
30 struct Treap{
31 int val;
32 int fix, siz;
33 Treap *ch[2];
34
35 void update(){
36 siz = 1;
37 if (ch[0] != NULL) siz += ch[0]->siz;
38 if (ch[1] != NULL) siz += ch[1]->siz;
39 }
40 };
41 //将t的d儿子换到t
42 void rotate(Treap *&t, int d){
43 Treap *p = t->ch[d];
44 t->ch[d] = p->ch[d ^ 1];
45 t->update();
46 p->ch[d ^ 1] = t;
47 p->update();
48 t = p;
49 return;
50 }
51 Treap *NEW(int val){
52 Treap *t = new Treap;
53 t->fix = rand();
54 t->val = val;
55 t->siz = 1;
56 t->ch[0] = t->ch[1] = NULL;
57 return t;
58 }
59 void insert(Treap *&t, int val){
60 if (t == NULL){
61 t = NEW(val);
62 return;
63 }
64 int d = (val >= t->val);
65 insert(t->ch[d], val);
66 if (t->ch[d]->fix > t->fix) rotate(t, d);
67 t->update();
68 }
69 int size(Treap *&t) {return (t == NULL) ? 0: t->siz;}
70 //统计比val大的数量,包括val!
71 int get(Treap *&t, int val){
72 if (t == NULL) return 0;
73 //右边都比他大..
74 if (val <= t->val) return size(t->ch[1]) + 1 + get(t->ch[0], val);
75 else return get(t->ch[1], val);
76 }
77 void erase(Treap *&t, int x){
78 int d;
79 if (x == t->val) d = -1;
80 else d = (x > t->val);//随意删除一个就行了
81
82 if (d == -1){
83 Treap *tmp = t;
84 if (t->ch[0] == NULL){//左儿子为0那么就变成右儿子
85 t = t->ch[1];
86 delete tmp;
87 }else if (t->ch[1] == NULL){
88 t = t->ch[0];
89 delete tmp;
90 }else{//还没到叶子转下去
91 int f = (t->ch[1]->fix > t->ch[0]->fix);
92 rotate(t, f);
93 erase(t->ch[f ^ 1], x);//注意转到另一边了
94 }
95 }else erase(t->ch[d], x);
96 if (t != NULL) t->update();
97 }
98
99 //------------------------以上为Treap------------------//
100
101 struct Node{//线段树的节点
102 int l, r;
103 Treap *t;//注意这个里面用动态内存分配...无奈.
104 Node *ch[2];
105 }*root, mem[MAXN * 2];
106 int n, q;//点数和询问总述数量
107 int head[MAXN * 2], to[MAXN * 2];//vector会爆?
108 int M, next[MAXN * 2], fa[MAXN];
109 int Time, data[MAXN], son[MAXN], siz[MAXN], pos[MAXN];//时间轴
110 int top[MAXN], tot, dep[MAXN];
111
112 void addEdge(int u, int v){
113 to[M] = v;
114 next[M]= head[u];
115 head[u] = M++;
116 }
117 void dfs_1(int u){
118 son[u] = 0;
119 siz[u] = 1;
120 for (int i = head[u];i != -1; i = next[i]){
121 int v = to[i];
122 if (v == fa[u]) continue;
123 fa[v] = u;
124 dep[v] = dep[u] + 1;
125 dfs_1(v);
126 siz[u] += siz[v];
127 if (siz[v] > siz[son[u]]) son[u] = v;
128 }
129 }
130 void dfs_2(int u, int top_node){
131 pos[u] = ++Time;
132 top[u] = top_node;
133 if (son[u]) dfs_2(son[u], top_node);
134 for (int i = head[u]; i != -1; i = next[i]){
135 int v = to[i];
136 if (v == fa[u] || v == son[u]) continue;
137 dfs_2(v, v);
138 }
139 }
140 Node *NEW(int l, int r){
141 Node *p = &mem[tot++];
142 p->l = l;
143 p->r = r;
144 p->t = NULL;//p里面的treap
145 p->ch[0] = p->ch[1] = NULL;
146 return p;
147 }
148 void build(Node *&t, int l, int r){
149 if (t == NULL){
150 t = NEW(l, r);
151 }
152 if (l == r) return;
153 int mid = (l + r) >> 1;
154 build(t->ch[0], l, mid);
155 build(t->ch[1], mid + 1, r);
156 }
157 //居然是单点修改OAO
158 //将l位置的路由器延迟时间由x变为y
159 void change(Node *&p, int l, int x, int y){
160 if (p->l == l && p->r == l){
161 if (x != INF) erase(p->t, x);//为INF的时候就是单纯的插入
162 insert(p->t, y);
163 return;
164 }
165 if (x != INF) erase(p->t, x);
166 insert(p->t, y);
167
168 int mid = (p->l + p->r) >> 1;
169 if (l <= mid) change(p->ch[0], l, x, y);
170 else change(p->ch[1], l, x, y);
171 }
172 //表示在l,r这一段内比val大的数的个数
173 int query(Node *&p, int l, int r, int val){
174 if (l <= p->l && p->r <= r) return get(p->t, val);
175 int mid = (p->l + p->r) >> 1;
176 int sum = 0;
177 if (l <= mid) sum += query(p->ch[0], l, r, val);
178 if (r > mid) sum += query(p->ch[1], l, r, val);
179 return sum;
180 }
181 void init(){
182 memset(head, -1, sizeof(head));
183 memset(dep, 0, sizeof(dep));//表示根到自己不包含根的节点数量
184 siz[0] = fa[1] = 0;
185 M = Time = 0;
186
187 scanf("%d%d", &n, &q);
188 for (int i = 1; i <= n; i++) scanf("%d", &data[i]);
189 for (int i = 1; i < n; i++){
190 int u, v;
191 scanf("%d%d", &u, &v);
192 addEdge(u, v);
193 addEdge(v, u);
194 }
195 dfs_1(1);
196 dfs_2(1, 1);
197 build(root, 1, Time);
198 for (int i = 1; i <= n; i++)
199 change(root, pos[i], INF, data[i]);
200 }
201 //返回在lr区间内比x大的数个数
202 int check(int l, int r, int x){
203 int sum = 0;
204 while (top[l] != top[r]){
205 //保证永远矮的往上爬
206 if (dep[top[l]] < dep[top[r]]) swap(l, r);
207 sum += query(root, pos[top[l]], pos[l], x);
208 l = fa[top[l]];
209 }
210 //显然l应该高一点
211 if (dep[l] > dep[r]) swap(l, r);
212 sum += query(root, pos[l], pos[r], x);
213 return sum;
214 }
215 int query(int L, int R, int k){
216 //首先二分最大值k
217 int Ans, l = -MAX, r = MAX;
218 while (l <= r){
219 int mid = (l + r) >> 1;
220 if (mid == 3)
221 printf("");
222 if (check(L, R, mid) >= k) Ans = mid, l = mid + 1;
223 else r = mid - 1;
224 }
225 //printf("%d", check(L, R, 3));
226 return Ans;
227 }
228 int search(int l, int r){
229 int sum = 0;
230 while (top[l] != top[r]){
231 if (dep[top[l]] < dep[top[r]]) swap(l, r);
232 sum += dep[l] - dep[top[l]] + 1;
233 l = fa[top[l]];
234 }
235 //dep[r]大
236 if (dep[l] > dep[r]) swap(l, r);
237 sum += dep[r] - dep[l] + 1;
238 return sum;
239 }
240 void work(){
241 for (int i = 1; i <= q; i++){
242
243 int l, r, k;
244 scanf("%d%d%d", &k, &l, &r);
245 //if (i == 5)
246 //printf("%d", k);
247 if (k == 0){//修改操作
248 change(root, pos[l], data[l], r);
249 data[l] = r;
250 }else{//查询
251 int num = search(l, r);//查询l到r之间的节点个数
252 if (k > num) {printf("invalid request!\n");continue;}
253 printf("%d\n", query(l, r, k));
254 }
255 }
256 }
257 void debug(){
258 /*Treap *root = NULL;
259 insert(root, 2);
260 printf("%d", get(root, 2));*/
261 //printf("%d", search(4, 2));
262 //for (int i = 1; i <= 5; i++) printf("%d\n", pos[i]);
263 //printf("%d", query(root, 2, 3, 3));
264 }
265
266 int main(){
267 //srand(time(0));
268
269 init();
270 work();
271 //debug();
272 return 0;
273 }