POJ 2104 Chairman of the tree template title

#include <iostream>
#include <cstdio>
#include <algorithm>
int const maxn = 200010;
using namespace std;
int a[maxn], b[maxn];
//第几个版本的根节点编号
int root[maxn << 5];
int lc[maxn << 5], rc[maxn << 5], sum[maxn << 5];
int sz;//节点个数
int n, m;
int true_n;


void build(int &rt, int l, int r) {
    rt = ++sz;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(lc[rt], l, mid);
    build(rc[rt], mid + 1, r);
}

int update(int id, int l, int r, int pos) {
    int _id = ++sz;
    lc[_id] = lc[id], rc[_id] = rc[id], sum[_id] = sum[id] + 1;
    if (l == r) return _id;
    int mid = (r + l) >> 1;
    if (pos <= mid)
        lc[_id] = update(lc[id], l, mid, pos);
    else
        rc[_id] = update(rc[id], mid + 1, r, pos);
    return _id;
}

int query(int p, int q, int l, int r, int k) {
    if (l == r) return l;
    int x = sum[lc[q]] - sum[lc[p]];
    int mid = (l + r) >> 1;
    if (x >= k)
        return query(lc[p], lc[q], l, mid, k);
    else
        return query(rc[p], rc[q], mid + 1, r, k - x);
}


int main() {
    while (~scanf("%d %d", &n, &m)) {
        sz = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            b[i] = a[i];
        }
        sort(b + 1, b + n + 1);
        true_n = unique(b + 1, b + n + 1) - b - 1;
        build(root[0], 1, true_n);
        for (int i = 1; i <= n; i++) {
            int pos = lower_bound(b + 1, b + true_n + 1, a[i]) - b;
            root[i] = update(root[i - 1], 1, true_n, pos);
        }
        while (m--) {
            int l, r, k;
            scanf("%d %d %d", &l, &r, &k);
            cout << b[query(root[l - 1], root[r], 1, true_n, k)] << endl;
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/woxiaosade/p/11421889.html