1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| const int MAXN = 200010;
struct node{ int l,r,cnt; }tree[15000000]; int root[MAXN]; int endd = 0; int num[MAXN]; int bucket[MAXN]; int siz; int n, m; int clone(int id){ tree[++endd] = tree[id]; return endd; } void buildtree(int p, int l, int r){ if(l == r) return; tree[p].l = ++endd; tree[p].r = ++endd; int m = (l + r) >> 1; buildtree(tree[p].l, l, m); buildtree(tree[p].r, m + 1, r); return; } int add(int p, int l, int r, int w){ p = clone(p); ++tree[p].cnt; if(l == r) return p; int m = (l + r) >> 1; if(w <= bucket[m]){ tree[p].l = add(tree[p].l, l, m, w); } else{ tree[p].r = add(tree[p].r, m + 1, r, w); } return p; } int ask(int p1, int p2,int l,int r, int k){ if(l == r) return bucket[l]; int m = (l + r) >> 1; if(k <= tree[tree[p2].l].cnt - tree[tree[p1].l].cnt) return ask(tree[p1].l, tree[p2].l, l, m, k); else return ask(tree[p1].r, tree[p2].r, m + 1, r, k - (tree[tree[p2].l].cnt - tree[tree[p1].l].cnt)); } int main() { n = read(), m = read(); rep(i,1,n){ num[i] = read(); bucket[i] = num[i]; } sort(bucket + 1, bucket + 1 + n); rep(i,1,n){ if(siz == 0 || bucket[i] > bucket[siz]) bucket[++siz] = bucket[i]; else bucket[siz] = bucket[i]; } buildtree(0,1,siz); rep(i,1,n){ root[i] = add(root[i - 1], 1, siz, num[i]); } rep(i,1,m){ int l = read(), r = read(), k = read(); printf("%d\n", ask(root[l - 1], root[r], 1, siz, k)); } return 0; }
|