划分树

查询还是没有get到点.

可以求第K小. 

(中位数问题 <--> 第K小)

int sorted[maxn];
int val[20][maxn];
int num[20][maxn];

void build(int l, int r, int deep) {
    if (l == r) return ;
    int mid = (l + r) / 2, i;
    int st_l = l, st_r = mid + 1, same = mid - l + 1;
    for (i=l; i<=r; ++i) 
        if (val[deep][i] < sorted[mid]) 
            same--;
    for (i=l; i<=r; ++i) {
        if (i == l) num[deep][i] = 0;
        else num[deep][i] = num[deep][i-1];
        
        if (val[deep][i] < sorted[mid]) {
            num[deep][i]++;
            val[deep+1][st_l++] = val[deep][i];
        } else if (val[deep][i] > sorted[mid]) {
            val[deep+1][st_r++] = val[deep][i];
        } else {
            if (same) {
                same--;
                num[deep][i]++;
                val[deep+1][st_l++] = val[deep][i];    
            } else {
                val[deep+1][st_r++] = val[deep][i];
            }
        }
    }
    build(l, mid, deep+1);
    build(mid+1, r, deep+1);
}

int query(int ql, int qr, int l, int r, int deep, int k) {
    int s, ss;
    if (l == r) return val[deep][ql];
    if (ql == l) {
        s = 0;
        ss = num[deep][qr];
    } else {
        s = num[deep][ql-1];
        ss = num[deep][qr] - s;
    }
    int mid = (l + r) / 2;
    int nl, nr;
    if (ss >= k) {
        nl = l + s;
        nr = l + num[deep][qr] - 1;
        return query(nl, nr, l, mid, deep+1, k);
    } else {
        nl = mid - l + 1 + ql - s;
        nr = mid - l + 1 + qr - s - ss;
        return query(nl, nr, mid+1, r, deep+1, k-ss);
    }
    
}
原文地址:https://www.cnblogs.com/cgjh/p/9657007.html