划分树
查询还是没有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); } }