1. 程式人生 > >板子4

板子4

cnblogs update query () while can n) class div

主席樹(求區間第K大)

int cnt, T[maxn];
struct Tree{
    int l, r, val;
} tre[maxn*40];

void init() {
    cnt = 0;
}

int build(int l, int r) {
    int nod = ++cnt;
    tre[nod].val = 0;
    if (l == r) return nod;
    int m = l + r >> 1;
    tre[nod].l = build(l, m);
    tre[nod].r = build(m+1, r);
    return nod;
}

int update(int pre, int l, int r, int val) {
    int nod = ++cnt;
    tre[nod] = tre[pre]; tre[nod].val++;
    if (l == r) return nod;
    int m = l + r >> 1;
    if (val <= m) tre[nod].l = update(tre[pre].l, l, m, val);
    else tre[nod].r = update(tre[pre].r, m+1, r, val);
    return nod;
}

int query(int v, int u, int l, int r, int k) {
    if (l == r) return l;
    int m = l + r >> 1;
    int num = tre[tre[u].l].val - tre[tre[v].l].val;    //左邊的數多少
    if (num >= k) return query(tre[v].l, tre[u].l, l, m, k);
    else return query(tre[v].r, tre[u].r, m + 1, r, k - num);
}

int a[maxn], n, m, b[maxn];

void solve() {
    while (cin >> n >> m) {
        init();
        for (int i = 1; i <= n; i++) {
            scanf("%d", a + i);
            b[i] = a[i];
        }
        sort(b+1, b+1+n);
        int xx = unique(b+1, b+1+n) - (b + 1);  //離散
        T[0] = build(1, xx);    //根節點
        for (int i = 1; i <= n; i++) {
            int h = lower_bound(b+1, b+1+n, a[i]) - (b + 1);
            T[i] = update(T[i-1], 1, xx, h+1);
        }
        while (m--) {
            int l, r, k; scanf("%d%d%d", &l, &r, &k);
            printf("%d\n", b[query(T[l-1], T[r], 1, xx, k)]);
        }
    }
}

  

板子4