hdu 2665 Kth number 主席樹
阿新 • • 發佈:2019-01-08
Kth number
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 12712 Accepted Submission(s): 3871
Problem Description Give you a sequence and ask you the kth big number of a inteval.
Input The first line is the number of the test cases.
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence.
Each of following m lines contains three integers s, t, k.
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]
Output For each test case, output m lines. Each line contains the kth big number.
Sample Input
Sample Output 2
#include <cstdio> #include <algorithm> #include <vector> #include <algorithm> using namespace std; const int maxn = 1e5 + 10; int T, n, m; int root[maxn * 20], lson[maxn * 20], rson[maxn * 20], sum[maxn * 20]; int a[maxn], cnt; vector <int> b; void build(int &o, int l, int r) { o = ++cnt; sum[o] = 0; if (l == r) return ; int m = (l + r) / 2; build(lson[o], l, m); build(rson[o], m + 1, r); } void update(int &o, int l, int r, int last, int pos) { o = ++cnt; lson[o] = lson[last]; rson[o] = rson[last]; sum[o] = sum[last] + 1; if (l == r) return ; int m = (l + r) / 2; if (pos <= m) update(lson[o], l, m, lson[last], pos); else update(rson[o], m + 1, r, rson[last], pos); } int query(int start, int end, int l, int r, int k) { if (l == r) return l; int m = (l + r) / 2; int cur = sum[lson[end]] - sum[lson[start]]; if (cur >= k) return query(lson[start], lson[end],l, m, k); else return query(rson[start], rson[end], m + 1, r, k - cur); } int main() { scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); b.clear(); cnt = 0; for (int i = 0; i < n; i++) { scanf("%d", &a[i]); b.push_back(a[i]); } sort(b.begin(), b.end()); b.erase(unique(b.begin(), b.end()), b.end()); build(root[0], 1, b.size()); for (int i = 0; i < n; i++) { update(root[i + 1], 1, b.size(), root[i], lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1); } while (m--) { int L, R, rank; scanf("%d%d%d", &L, &R, &rank); printf("%d\n", b[query(root[L - 1], root[R], 1, b.size(), rank) - 1]); } } return 0; }