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
| #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std;
#define debug(x) cout << #x << " is " << x << endl #define inc(i, a, b) for (int i = a; i <= b; ++i) typedef long long ll; const int INF = 0x3f3f3f3f, N = 1e5 + 5;
struct Op { int l, r, k; }op[N];
struct Node { int ls, rs, cnt; }tree[N*400];
int n, m, tot, t, cl, cr; int a[N], b[N<<1], root[N]; int L[20], R[20];
int build(int l, int r) { int p = ++tot; tree[p].cnt = 0; if (l == r) return p; int mid = (l + r) >> 1; tree[p].ls = build(l, mid); tree[p].rs = build(mid + 1, r); return p; }
int update(int pre, int l, int r, int x, int v) { int p = ++tot; tree[p] = tree[pre]; if (l == r) { tree[p].cnt += v; return p; } int mid = (l + r) >> 1; if (x <= mid) tree[p].ls = update(tree[pre].ls, l, mid, x, v); else tree[p].rs = update(tree[pre].rs, mid + 1, r, x, v); tree[p].cnt = tree[tree[p].ls].cnt + tree[tree[p].rs].cnt; return p; }
int query(int l, int r, int k) { if (l == r) return l; int mid = (l + r) >> 1, sum = 0; for (int i = 1; i <= cl; ++i) sum -= tree[tree[L[i]].ls].cnt; for (int i = 1; i <= cr; ++i) sum += tree[tree[R[i]].ls].cnt; if (k <= sum) { for (int i = 1; i <= cl; ++i) L[i] = tree[L[i]].ls; for (int i = 1; i <= cr; ++i) R[i] = tree[R[i]].ls; return query(l, mid, k); } else { for (int i = 1; i <= cl; ++i) L[i] = tree[L[i]].rs; for (int i = 1; i <= cr; ++i) R[i] = tree[R[i]].rs; return query(mid + 1, r, k - sum); } }
int lowbit(int x) { return x & -x; }
void add(int x, int v) { int id = lower_bound(b + 1, b + t + 1, a[x]) - b; for (; x <= n; x += lowbit(x)) root[x] = update(root[x], 1, t, id, v); }
int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); b[++t] = a[i]; } char str[2]; for (int i = 1; i <= m; ++i) { scanf("%s", str); if (str[0] == 'Q') scanf("%d%d%d", &op[i].l, &op[i].r, &op[i].k); else if (str[0] == 'C') { scanf("%d%d", &op[i].l, &op[i].r); b[++t] = op[i].r; op[i].k = 0; } } sort(b + 1, b + t + 1); t = unique(b + 1, b + t + 1) - (b + 1); root[0] = build(1, t); for (int i = 1; i <= n; ++i) add(i, 1); for (int i = 1; i <= m; ++i) { if (op[i].k) { cl = cr = 0; for (int j = op[i].l - 1; j; j -= lowbit(j)) L[++cl] = root[j]; for (int j = op[i].r; j; j -= lowbit(j)) R[++cr] = root[j]; int ans = query(1, t, op[i].k); printf("%d\n", b[ans]); } else { add(op[i].l, -1); a[op[i].l] = op[i].r; add(op[i].l, 1); } } return 0; }
|