#include using namespace std; using ll = long long; // Persistent segment-tree nodes pooled struct Node { int lc, rc; int cnt; }; static const int MAXN = 200000; static const int MAXQ = 200000; static const int POOL_SIZE = (MAXN + MAXQ) * 25; static Node pool[POOL_SIZE]; static int pool_ptr = 1; int new_node(int from = 0) { int id = pool_ptr++; pool[id] = pool[from]; return id; } int update_node(int node, int L, int R, int pos, int delta) { int id = new_node(node); pool[id].cnt += delta; if (L < R) { int mid = (L + R) >> 1; if (pos <= mid) pool[id].lc = update_node(pool[id].lc, L, mid, pos, delta); else pool[id].rc = update_node(pool[id].rc, mid+1, R, pos, delta); } return id; } int N, Q, M; vector vals; vector A; vector bit_root; // size N+1 void bit_update(int idx, int pos, int delta) { for (int i = idx; i <= N; i += i & -i) { bit_root[i] = update_node(bit_root[i], 0, M-1, pos, delta); } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin >> N >> Q; A.resize(N); vals.reserve(N + Q); for (int i = 0; i < N; i++){ cin >> A[i]; vals.push_back(A[i]); } struct Qry{ int t, i, x, l, r; }; vector qs(Q); for (int qi = 0; qi < Q; qi++){ int t; cin >> t; qs[qi].t = t; if (t == 1){ cin >> qs[qi].i >> qs[qi].x; qs[qi].i--; vals.push_back(qs[qi].x); } else { cin >> qs[qi].l >> qs[qi].r; qs[qi].l--; qs[qi].r--; } } sort(vals.begin(), vals.end()); vals.erase(unique(vals.begin(), vals.end()), vals.end()); M = vals.size(); auto getId = [&](int v){ return int(lower_bound(vals.begin(), vals.end(), v) - vals.begin()); }; bit_root.assign(N+1, 0); pool[0] = {0,0,0}; for (int i = 0; i < N; i++){ bit_update(i+1, getId(A[i]), +1); } // scratch arrays for nodes (max BIT height ~18) int maxH = 0; while((1< r_nodes(maxH), l_nodes(maxH); for (auto &q : qs){ if (q.t == 1){ int idx = q.i; int oldv = getId(A[idx]); int newv = getId(q.x); if (oldv != newv){ bit_update(idx+1, oldv, -1); bit_update(idx+1, newv, +1); A[idx] = q.x; } } else { int l = q.l, r = q.r; int k = ((r-l+1) + 1) >> 1; int sz = 0; for (int i = r+1; i > 0; i -= i & -i) r_nodes[sz++] = bit_root[i]; int sz2 = 0; for (int i = l; i > 0; i -= i & -i) l_nodes[sz2++] = bit_root[i]; int L = 0, R = M-1; while (L < R){ int mid = (L+R) >> 1; ll cntL = 0; for (int j = 0; j < sz; j++) cntL += pool[ pool[r_nodes[j]].lc ].cnt; for (int j = 0; j < sz2; j++) cntL -= pool[ pool[l_nodes[j]].lc ].cnt; if (k <= cntL){ for (int j = 0; j < sz; j++) r_nodes[j] = pool[r_nodes[j]].lc; for (int j = 0; j < sz2; j++) l_nodes[j] = pool[l_nodes[j]].lc; R = mid; } else { k -= cntL; for (int j = 0; j < sz; j++) r_nodes[j] = pool[r_nodes[j]].rc; for (int j = 0; j < sz2; j++) l_nodes[j] = pool[l_nodes[j]].rc; L = mid+1; } } cout << vals[L] << '\n'; } } return 0; }