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
| #include <iostream> #include <algorithm> #include <cstring> #include <cstdio>
using namespace std;
const int maxn = 3e+5 + 5; const int maxp = maxn * 50;
struct opt { int typ, a, b, c; }opl[maxn]; int n, m, lp[maxn], rp[maxn]; int id[maxn], s[maxn]; int ls[maxp], rs[maxp], su[maxp], cnt; int val[maxn], cpy[maxn], tot;
inline int rd() { register int x = 0, f = 0, c = getchar(); while (!isdigit(c)) { if (c == '-') f = 1; c = getchar(); } while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar(); return f ? -x : x; } inline void init(int l, int r) { for (; l; l -= (l & -l)) lp[l] = id[l]; for (; r; r -= (r & -r)) rp[r] = id[r]; } inline void toLeft(int l, int r) { for (; l; l -= (l & -l)) lp[l] = ls[lp[l]]; for (; r; r -= (r & -r)) rp[r] = ls[rp[r]]; } inline void toRight(int l, int r) { for (; l; l -= (l & -l)) lp[l] = rs[lp[l]]; for (; r; r -= (r & -r)) rp[r] = rs[rp[r]]; } inline int getLeft(int x, int *p) { int ret = 0; for (; x; x -= (x & -x)) ret += su[ls[p[x]]]; return ret; } int update(int lst, int l, int r, int p, int x) { int newrt = ++cnt; ls[newrt] = ls[lst]; rs[newrt] = rs[lst]; su[newrt] = su[lst] + x; if (l == r) return newrt; int mid = (l + r) >> 1; if (p <= mid) ls[newrt] = update(ls[lst], l, mid, p, x); else rs[newrt] = update(rs[lst], mid + 1, r, p, x); return newrt; } int getRank(int l, int r, int L, int R, int x) { if (l == r) return 0; int mid = (l + r) >> 1; if (x <= mid) { toLeft(L, R); return getRank(l, mid, L, R, x); } else { int tmp = getLeft(R, rp) - getLeft(L, lp); toRight(L, R); return getRank(mid + 1, r, L, R, x) + tmp; } } int getKth(int l, int r, int L, int R, int k) { if (l == r) return cpy[l]; int mid = (l + r) >> 1; int tmp = getLeft(R, rp) - getLeft(L, lp); if (k <= tmp) { toLeft(L, R); return getKth(l, mid, L, R, k); } else { toRight(L, R); return getKth(mid + 1, r, L, R, k - tmp); } } inline void add(int p, int x, int v) { for (; p <= n; p += (p & -p)) id[p] = update(id[p], 1, tot, x, v); }
int main() { n = rd(); m = rd(); for (int i = 1; i <= n; ++i) val[i] = cpy[i] = rd(); tot = n; for (int i = 1; i <= m; ++i) { opl[i].typ = rd(); if (opl[i].typ == 3) { opl[i].a = rd(); opl[i].b = rd(); cpy[++tot] = opl[i].b; } else { opl[i].a = rd(); opl[i].b = rd(); opl[i].c = rd(); if (opl[i].typ != 2) cpy[++tot] = opl[i].c; } } sort(cpy + 1, cpy + 1 + tot); tot = unique(cpy + 1, cpy + 1 + tot) - (cpy + 1); for (int i = 1; i <= n; ++i) { int x = lower_bound(cpy + 1, cpy + 1 + tot, val[i]) - cpy; add(i, x, 1); } for (int i = 1; i <= m; ++i) { if (opl[i].typ == 3) { int pos = opl[i].a, newval = opl[i].b; int ori = lower_bound(cpy + 1, cpy + 1 + tot, val[pos]) - cpy; int upd = lower_bound(cpy + 1, cpy + 1 + tot, newval) - cpy; add(pos, ori, -1); val[pos] = newval; add(pos, upd, 1); } else { int ql = opl[i].a - 1, qr = opl[i].b, qv; init(ql, qr); if (opl[i].typ != 2) qv = lower_bound(cpy + 1, cpy + 1 + tot, opl[i].c) - cpy; if (opl[i].typ == 1) printf("%d\n", getRank(1, tot, ql, qr, qv) + 1); else if (opl[i].typ == 2) printf("%d\n", getKth(1, tot, ql, qr, opl[i].c)); else if (opl[i].typ == 4) { int k = getRank(1, tot, ql, qr, qv); if (!k) puts("-2147483647"); else { init(ql, qr); printf("%d\n", getKth(1, tot, ql, qr, k)); } } else { int k = getRank(1, tot, ql, qr, qv + 1); if (k > opl[i].b - opl[i].a) puts("2147483647"); else { init(ql, qr); printf("%d\n", getKth(1, tot, ql, qr, k + 1)); } } } } return 0; }
|