P3834 【模板】可持久化线段树 2

乎语百科 329 0

P3834

主席树模板,求区间第k小。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define lc tr[i].ch[0]
 4 #define rc tr[i].ch[1]
 5 #define Lc tr[j].ch[0]
 6 #define Rc tr[j].ch[1]
 7 #define mid ((l + r) >> 1)
 8 const int N = 2e5 + 10;
 9 int n, m, a[N], b[N];
10 int cnt, rt[N];
11 struct node {
12     int num, ch[2];
13 }tr[N * 20];
14 void update(int &i, int j, int l, int r, int k) {
15     i = ++cnt;//编号
16     tr[i] = tr[j];//复制之前版本
17     ++ tr[i].num;
18     if (l == r) return ;
19     if (k <= mid) update(lc, Lc, l, mid, k);
20     else update(rc, Rc, mid + 1, r, k);
21 }
22 int query(int i, int j, int l, int r, int k) {
23     if (l == r) return l;//返回下标
24     int s = tr[Lc].num - tr[lc].num;
25     if (k <= s) return query(lc, Lc, l, mid, k);
26     else return query(rc, Rc, mid + 1, r, k - s);
27 }
28 int main() {
29     scanf("%d %d", &n, &m);
30     for (int i = 1; i <= n; i ++) {
31         scanf("%d", &a[i]);
32         b[i] = a[i];
33     }
34     sort(b + 1, b + n + 1);
35     int tot = unique(b + 1, b + n + 1) - b - 1;
36     cnt = 0, rt[0] = 0;
37     for (int i = 1; i <= n; i ++)
38     update(rt[i], rt[i - 1], 1, tot, lower_bound(b + 1, b + tot + 1, a[i]) - b);
39     int x, y, k;
40     while (m --) {
41         scanf("%d %d %d", &x, &y, &k);
42         printf("%d\n", b[query(rt[x - 1], rt[y], 1, tot, k)]);
43     }
44     return 0;
45 }

标签:

留言评论

  • 这篇文章还没有收到评论,赶紧来抢沙发吧~