poj 2104 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\n", 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 }