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\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 }
View Code

 

你可能感兴趣的:(number)