|
| 1 | +#include <bits/stdc++.h> |
| 2 | +using namespace std; |
| 3 | + |
| 4 | +typedef unsigned short usint; |
| 5 | +typedef unsigned uint; |
| 6 | +typedef long lint; |
| 7 | +typedef short sint; |
| 8 | +typedef long double ld; |
| 9 | +typedef long long llint; |
| 10 | +typedef unsigned long ulint; |
| 11 | +typedef unsigned long long ullint; |
| 12 | + |
| 13 | +#define INF (1<<30) |
| 14 | +#define MOD 1000000007 |
| 15 | +#define mp make_pair |
| 16 | +#define mt make_tuple |
| 17 | +#define pii pair <int,int> |
| 18 | +#define pcc pair <char,char> |
| 19 | +#define pss pair <string,string> |
| 20 | +#define all(c) c.begin(),c.end() |
| 21 | +#define ms(name,val) memset(name, val, sizeof name) |
| 22 | +#define np nullptr |
| 23 | + |
| 24 | + |
| 25 | +int A[100001]; |
| 26 | + |
| 27 | +struct Node |
| 28 | +{ |
| 29 | + int mn, mx; |
| 30 | + vector <int> B; |
| 31 | + Node *c[2]; |
| 32 | + |
| 33 | + Node(int _mn = INT_MAX, int _mx = INT_MIN) |
| 34 | + { |
| 35 | + mn = _mn; |
| 36 | + mx = _mx; |
| 37 | + c[0] = c[1] = np; |
| 38 | + } |
| 39 | +}; |
| 40 | + |
| 41 | +void delTree(Node *&x) |
| 42 | +{ |
| 43 | + if (x == np) return; |
| 44 | + delTree(x->c[0]); |
| 45 | + delTree(x->c[1]); |
| 46 | + delete x; |
| 47 | +} |
| 48 | + |
| 49 | +inline void upd(Node *&x, int &v) |
| 50 | +{ |
| 51 | + if (x == np) return; |
| 52 | + x->mn = min(x->mn,v); |
| 53 | + x->mx = max(x->mx,v); |
| 54 | +} |
| 55 | + |
| 56 | +void Build(Node *&x, int *from, int *to) |
| 57 | +{ |
| 58 | + if (x->mn == x->mx || from >= to) return; |
| 59 | + x->B.push_back(0); |
| 60 | + int mid = (x->mn+x->mx)>>1; |
| 61 | + Node *L = new Node, *R = new Node; |
| 62 | + auto f = [mid](int &x) { return (x <= mid); }; |
| 63 | + |
| 64 | + for (auto it = from; it != to; ++it) |
| 65 | + { |
| 66 | + x->B.push_back(x->B.back()+f(*it)); |
| 67 | + if (*it <= mid) upd(L,*it); else upd(R,*it); |
| 68 | + } |
| 69 | + |
| 70 | + auto pivot = stable_partition(from, to, f); |
| 71 | + x->c[0] = L, x->c[1] = R; |
| 72 | + Build(x->c[0], from, pivot); |
| 73 | + Build(x->c[1], pivot, to); |
| 74 | + if (L->mn == INT_MAX) x->c[0] = np, delete L; |
| 75 | + if (R->mn == INT_MAX) x->c[1] = np, delete R; |
| 76 | +} |
| 77 | + |
| 78 | +int Frequency(Node *x, int L, int R, int &v) // return frequency of number 'v' in range [L,R] |
| 79 | +{ |
| 80 | + while (x != np) |
| 81 | + { |
| 82 | + if (v < x->mn || v > x->mx) return 0; |
| 83 | + if (x->mn == x->mx) return R-L; |
| 84 | + int mid = (x->mn+x->mx)>>1; |
| 85 | + |
| 86 | + if (v <= mid) |
| 87 | + L = x->B[L], R = x->B[R], x = x->c[0]; |
| 88 | + else |
| 89 | + L -= x->B[L], R -= x->B[R], x = x->c[1]; |
| 90 | + } |
| 91 | + |
| 92 | + return 0; |
| 93 | +} |
| 94 | + |
| 95 | +int LTE(Node *x, int L, int R, int &v) // returns count of numbers less than or equal to 'v' in range [L,R] |
| 96 | +{ |
| 97 | + if (L > R || v < x->mn) return 0; |
| 98 | + if (x->mx <= v) return R-L; |
| 99 | + return LTE(x->c[0], x->B[L], x->B[R], v)+LTE(x->c[1], L-x->B[L], R-x->B[R], v); |
| 100 | +} |
| 101 | + |
| 102 | +int Kth(Node *x, int L, int R, int k) // returns k-th number in range [L,R], aka k-th order statistic |
| 103 | +{ |
| 104 | + if (L > R) return 0; |
| 105 | + if (x->mn == x->mx) return x->mn; |
| 106 | + int cntLeft = x->B[R]-x->B[L]; |
| 107 | + if (k <= cntLeft) return Kth(x->c[0], x->B[L], x->B[R], k); |
| 108 | + return Kth(x->c[1], L-x->B[L], R-x->B[R], k-cntLeft); |
| 109 | +} |
| 110 | + |
| 111 | +int main() |
| 112 | +{ |
| 113 | + ios_base::sync_with_stdio(0); |
| 114 | + |
| 115 | + |
| 116 | + int n, q; |
| 117 | + cin >> n; |
| 118 | + Node *root = new Node; |
| 119 | + |
| 120 | + for (int t1 = 1; t1 <= n; ++t1) |
| 121 | + { |
| 122 | + cin >> A[t1]; |
| 123 | + upd(root,A[t1]); |
| 124 | + } |
| 125 | + |
| 126 | + Build(root, A+1, A+n+1); |
| 127 | + cin >> q; |
| 128 | + |
| 129 | + while (q) |
| 130 | + { |
| 131 | + --q; |
| 132 | + char c; |
| 133 | + int L, R, v; |
| 134 | + cin >> c; |
| 135 | + |
| 136 | + if (c == 'F') |
| 137 | + { |
| 138 | + cin >> v >> L >> R; |
| 139 | + cout << Frequency(root, L-1, R, v) << '\n'; |
| 140 | + } |
| 141 | + else if (c == 'L') |
| 142 | + { |
| 143 | + cin >> v >> L >> R; |
| 144 | + cout << LTE(root, L-1, R, v) << '\n'; |
| 145 | + } |
| 146 | + else if (c == 'K') |
| 147 | + { |
| 148 | + cin >> v >> L >> R; |
| 149 | + cout << Kth(root, L-1, R, v) << '\n'; |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + delTree(root), root = np; |
| 154 | + |
| 155 | + |
| 156 | + return 0; |
| 157 | +} |
0 commit comments