可持久化线段树是可以查询历史版本的数据结构,比如说查询区间第k大的数,那么我们需要查询到1-r 和 1- (l - 1) 数据的分布情况,以完成查询。

 

  2015年11月25日

    模板题 poj2104

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define rep(i, a, b) for (int i = a; i <= b; i++)
 5 #define REP(i, a, b) for (int i = a; i < b; i++)
 6 #define drep(i, a, b) for (int i = a; i >= b; i--)
 7 #define mp make_pair
 8 #define pb push_back
 9 #define clr(x) memset(x, 0, sizeof(x))
10 #define xx first
11 #define yy second
12 using namespace std;
13 typedef long long i64;
14 typedef pair<int, int> pii;
15 const int inf = ~0U>>1;
16 const i64 INF = ~0ULL >> 1;
17 //*********************************
18 
19 const int maxn = 100005, maxm = 2060965;
20 int Sum[maxm];
21 int Lson[maxm], Rson[maxm];
22 
23 int read() {
24     int l = 1, s = 0;
25     char ch = getchar();
26     while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar(); }
27     while (ch >= '0' && ch <= '9') { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar(); }
28     return l * s;
29 }
30 
31 int totnode;
32 void build(int x, int &y, int l, int r, int v) {
33     Sum[y = ++totnode] = Sum[x] + 1;
34     if (l == r) return;
35     int mid = l + r >> 1;
36     if (v <= mid) {
37         Rson[y] = Rson[x];
38         build(Lson[x], Lson[y], l, mid, v);
39     }
40     else {
41         Lson[y] = Lson[x];
42         build(Rson[x], Rson[y], mid + 1, r, v);
43     }
44 }
45 
46 int query(int x, int y, int l, int r, int k) {
47     if (l == r) return l;
48     int mid = l + r >> 1, tmp = Sum[Lson[y]] - Sum[Lson[x]];
49     if (tmp >= k) return query(Lson[x], Lson[y], l, mid, k);
50     else return query(Rson[x], Rson[y], mid + 1, r, k - tmp);
51 }
52 
53 int val[maxn], hsh[maxn], root[maxn];
54 int main() {
55     int n, m;
56     n = read(), m = read();
57     rep(i, 1, n) val[i] = read(), hsh[i] = val[i];
58     sort(hsh + 1, hsh + 1 + n); int cd = unique(hsh + 1, hsh + 1 + n) - (hsh + 1);
59     rep(i, 1, n) val[i] = lower_bound(hsh + 1, hsh + 1 + cd, val[i]) - hsh;
60     
61     int cnt = cd;
62     for (int i = 1; i <= n; i++)
63         build(root[i - 1], root[i], 1, cnt, val[i]);
64    
65     for (int i = 1; i <= m; i++) {
66         int x, y, k; x = read(), y = read(), k = read();
67         printf("%d\n", hsh[query(root[x - 1], root[y], 1, cnt, k)]);
68     }
69 
70     return 0;
71 }
View Code

相关文章:

  • 2021-11-02
  • 2021-09-30
  • 2021-07-05
  • 2022-02-09
  • 2022-02-11
  • 2021-08-17
猜你喜欢
  • 2021-10-18
  • 2021-09-07
  • 2021-09-27
相关资源
相似解决方案