样例都过不去
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lid (id << 1)
#define rid (id << 1 | 1)
const int N = 5e4+5;
struct trnode{
int ls, rs;
int key, pri, siz;
}treap[N << 6];
int tsiz;
void update(int rt){
treap[rt].siz = treap[treap[rt].ls].siz + treap[treap[rt].rs].siz + 1;
}
void newnode(int x){
++tsiz;
treap[tsiz].siz = 1;
treap[tsiz].ls = treap[tsiz].rs = 0;
treap[tsiz].key = x;
treap[tsiz].pri = rand();
}
void split(int rt, int x, int &l, int &r){
if (rt == 0){
l = r = 0;
return;
}
if (treap[rt].key <= x) l = rt, split(treap[rt].rs, x, treap[rt].rs, r);
else r = rt, split(treap[rt].ls, x, l, treap[rt].ls);
update(rt);
}
int merge(int l, int r){
if (l == 0 || r == 0) return l + r;
if (treap[l].pri > treap[r].pri){
treap[l].rs = merge(treap[l].rs, r);
update(l);
return l;
}
else{
treap[r].ls = merge(l, treap[r].ls);
update(r);
return r;
}
}
int insert(int &root, int x){
int l, r;
split(root, x, l, r);
newnode(x);
root = merge(merge(l, tsiz), r);
return tsiz;
}
void del(int &root, int x){
int l, m, r;
split(root, x, l, r);
split(l, x - 1, l, m);
m = merge(treap[m].ls, treap[m].rs);
root = merge(merge(l, m), r);
}
int rnk(int &root, int x){
int l, r, res;
split(root, x - 1, l, r);
res = treap[l].siz + 1;
root = merge(l, r);
return res;
}
int gkth(int rt, int k){
if (k == treap[treap[rt].ls].siz + 1) return rt;
if (k <= treap[treap[rt].ls].siz) return gkth(treap[rt].ls, k);
return gkth(treap[rt].rs, k - treap[treap[rt].ls].siz - 1);
}
int kth(int rt, int k){
return treap[gkth(rt, k)].key;
}
int kth1(int rt, int k){
return kth(rt, tsiz - k + 1);
}
int pre(int &root, int x){
int l, r, res;
split(root, x - 1, l, r);
res = kth(l, treap[l].siz);
root = merge(l, r);
return res;
}
int suc(int &root, int x){
int l, r, res;
split(root, x, l, r);
res = kth(r, 1);
root = merge(l, r);
return res;
}
struct node{
int l, r;
}tr[N << 2];
int root[N << 2], a[N], n, q;
void build (int id, int l, int r){
tr[id].l = l;
tr[id].r = r;
for (int i = l;i <= r;i++) insert(root[id], a[i]);
if (l == r) return;
int mid = (l + r) >> 1;
build(lid, l, mid);
build(rid, mid + 1, r);
}
int qrank(int id, int l, int r, int x){
if (tr[id].r < l || tr[id].l > r) return 0;
if (l <= tr[id].l && tr[id].r <= r) return rnk(root[id], x) - 1;
return qrank(lid, l, r, x) + qrank(rid, l, r, x);
}
int qkth(int l, int r, int rk){
int x = 0, y = 1e8, res = -1;
while (x <= y){
int mid = (x + y) >> 1;
if (qrank(1, l, r, mid) + 1 <= rk){
res = mid;
x = mid + 1;
}
else y = mid - 1;
}
return res;
}
void update(int id, int pos, int k){
del(root[id], a[pos]);
insert(root[id], k);
if (tr[id].l == tr[id].r) return;
int mid = (tr[id].l + tr[id].r) >> 1;
if (pos <= mid) update(lid, pos, k);
else update(rid, pos, k);
}
int qpre(int id, int l, int r, int k){
if (tr[id].r < l || tr[id].l > r) return -2147483647;
if (l <= tr[id].l && tr[id].r <= r){
return pre(root[id], k);
}
return max(qpre(lid, l, r, k), qpre(rid, l, r, k));
}
int qsuc(int id, int l, int r, int k){
if (tr[id].r < l || tr[id].l > r) return 2147483647;
if (l <= tr[id].l && tr[id].r <= r) return suc(root[id], k);
return min(qsuc(lid, l, r, k), qsuc(rid, l, r, k));
}
int main(){
srand(time(NULL));
cin >> n >> q;
for (int i = 1;i <= n;i++){
cin >> a[i];
}
while (q--){
int op, pos, l, r, k;
cin >> op;
if (op == 3){
cin >> pos >> k;
update(1, pos, k);
a[pos] = k;
}
else{
cin >> l >> r >> k;
if (op == 1){
cout << qrank(1, l, r, k) << '\n';
}
else if (op == 2){
cout << qkth(l, r, k) << '\n';
}
else if (op == 4){
cout << qpre(1, l, r, k) << '\n';
}
else if (op == 5){
cout << qsuc(1, l, r, k) << '\n';
}
}
}
return 0;
}