描述
静态区间第k小值
分析
- 改了一个主席树的模板, 改成了数组版.
- 感觉数组的要简洁好多.
- 主席树的讲解:http://hi.baidu.com/lov_zyf/item/87b578342e73fc83f5e4ad3d
- 感觉写的特别好.
代码
#include
#include
using namespace std;
const int maxn = 100000 + 10;
const int maxnode = 3000000 + 10;
int root[maxn], A[maxn], T[maxn];
int v[maxnode], s[maxnode], lc[maxnode], rc[maxnode];
int cnt;
#define M (L+R>>1)
void build(int& x, int y, int L, int R, int d) {
x = ++cnt;
if(L == R) v[x] = v[y] + 1;
else {
if(d <= T[M]) build(lc[x], lc[y], L, M, d), rc[x] = rc[y];
else build(rc[x], rc[y], M+1, R, d), lc[x] = lc[y];
}
s[x] = v[x] + s[lc[x]] + s[rc[x]];
}
int query(int x, int y, int L, int R, int k) {
if(L == R) return T[L];
int ls = s[lc[y]] - s[lc[x]];
if(ls >= k) return query(lc[x], lc[y], L, M, k);
return query(rc[x], rc[y], M+1, R, k-ls);
}
int main()
{
freopen("kth.in", "r", stdin);
freopen("kth.out", "w", stdout);
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &A[i]), T[i] = A[i];
sort(T+1, T+n+1);
int tot = unique(T+1, T+n+1)-T-1;
for(int i = 1; i <= n; i++) build(root[i], root[i-1], 1, tot, A[i]);
for(int i = 1; i <= m; i++) {
int L, R, k;
scanf("%d %d %d", &L, &R, &k);
printf("%d\n", query(root[L-1], root[R], 1, tot, k));
}
return 0;
}