POJ 2104 && POJ 2761 (静态区间第k大,主席树)

查询区间第K大,而且没有修改。

使用划分树是可以做的。

 

作为主席树的入门题,感觉太神奇了,Orz

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013-9-4 20:13:20
  4 File Name     :POJ2104.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 
 21 const int MAXN = 100010;
 22 const int M = MAXN * 30;
 23 int n,q,m,tot;
 24 int a[MAXN], t[MAXN];
 25 int T[M], lson[M], rson[M], c[M];
 26 
 27 void Init_hash()
 28 {
 29     for(int i = 1; i <= n;i++)
 30         t[i] = a[i];
 31     sort(t+1,t+1+n);
 32     m = unique(t+1,t+1+n)-t-1;
 33 }
 34 int build(int l,int r)
 35 {
 36     int root = tot++;
 37     c[root] = 0;
 38     if(l != r)
 39     {
 40         int mid = (l+r)>>1;
 41         lson[root] = build(l,mid);
 42         rson[root] = build(mid+1,r);
 43     }
 44     return root;
 45 }
 46 int hash(int x)
 47 {
 48     return lower_bound(t+1,t+1+m,x) - t;
 49 }
 50 int update(int root,int pos,int val)
 51 {
 52     int newroot = tot++, tmp = newroot;
 53     c[newroot] = c[root] + val;
 54     int l = 1, r = m;
 55     while(l < r)
 56     {
 57         int mid = (l+r)>>1;
 58         if(pos <= mid)
 59         {
 60             lson[newroot] = tot++; rson[newroot] = rson[root];
 61             newroot = lson[newroot]; root = lson[root];
 62             r = mid;
 63         }
 64         else
 65         {
 66             rson[newroot] = tot++; lson[newroot] = lson[root];
 67             newroot = rson[newroot]; root = rson[root];
 68             l = mid+1;
 69         }
 70         c[newroot] = c[root] + val;
 71     }
 72     return tmp;
 73 }
 74 int query(int left_root,int right_root,int k)
 75 {
 76     int l = 1, r = m;
 77     while( l < r)
 78     {
 79         int mid = (l+r)>>1;
 80         if(c[lson[left_root]]-c[lson[right_root]] >= k )
 81         {
 82             r = mid;
 83             left_root = lson[left_root];
 84             right_root = lson[right_root];
 85         }
 86         else
 87         {
 88             l = mid + 1;
 89             k -= c[lson[left_root]] - c[lson[right_root]];
 90             left_root = rson[left_root];
 91             right_root = rson[right_root];
 92         }
 93     }
 94     return l;
 95 }
 96 int main()
 97 {
 98     //freopen("in.txt","r",stdin);
 99     //freopen("out.txt","w",stdout);
100     while(scanf("%d%d",&n,&q) == 2)
101     {
102         tot = 0;
103         for(int i = 1;i <= n;i++)
104             scanf("%d",&a[i]);
105         Init_hash();
106         T[n+1] = build(1,m);
107         for(int i = n;i ;i--)
108         {
109             int pos = hash(a[i]);
110             T[i] = update(T[i+1],pos,1);
111         }
112         while(q--)
113         {
114             int l,r,k;
115             scanf("%d%d%d",&l,&r,&k);
116             printf("%d\n",t[query(T[l],T[r+1],k)]);
117         }
118     }
119     return 0;
120 }

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(poj)