poj 2104 K-th Number(可持久线段树)

K-th Number

持久化:http://www.cnblogs.com/tedzhao/archive/2008/11/12/1332112.html

结构:http://www.docin.com/p-627462377.html

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 const int N = 100010;
 8 int n, m, tot;
 9 int a[N], x[N], xcnt;
10 int T[N*20], ls[N*20], rs[N*20], sum[N*20];
11 
12 void build(int l, int r ,int &rt)
13 {
14     rt=++tot;
15     sum[rt]=0;
16     if(l==r) return ;
17     int m=(l+r)>>1;
18     build(l, m, ls[rt]);
19     build(m+1,r,rs[rt]);
20 }
21 
22 void update(int last, int p, int l, int r, int &rt)
23 {
24     rt = ++tot;
25     ls[rt]=ls[last], rs[rt]=rs[last], sum[rt]=sum[last]+1;
26     if(l==r) return ;
27     int m = (l+r)>>1;
28     if(p<=m) update(ls[last], p, l, m, ls[rt]);
29     else update(rs[last], p, m+1, r, rs[rt]);
30 }
31 
32 int query(int ss, int tt, int l, int r, int k)
33 {
34     if(l==r) return l;
35     int m = (l+r)>>1;
36     int num = sum[ls[tt]] - sum[ls[ss]];
37     if(k<=num) return query(ls[ss], ls[tt], l, m, k);
38     else return query(rs[ss], rs[tt], m+1, r, k-num);
39     return 0;
40 }
41 
42 void solve()
43 {
44     tot = 0;
45     for(int i=1; i<=n; i++)
46     {
47         scanf("%d", &a[i]);
48         x[i] = a[i];
49     }
50     sort(x+1, x+n+1);
51     xcnt = unique(x+1, x+1+n)-x-1;
52     for(int i=1; i<=n; i++) a[i] = lower_bound(x+1, x+n+1, a[i])-x;
53     build(1, xcnt, T[0]);
54     for(int i=1; i<=n; i++) update(T[i-1],a[i],1,xcnt,T[i]);
55     int l, r, k;
56     while(m--)
57     {
58         scanf("%d%d%d", &l, &r, &k);
59         printf("%d
", x[query(T[l-1],T[r],1,xcnt,k)]);
60     }
61 }
62 
63 int main()
64 {
65     while(scanf("%d%d", &n, &m)>0 ) solve();
66     return 0;
67 }
View Code
原文地址:https://www.cnblogs.com/zyx1314/p/3928464.html