poj2761_划分树

题意:给一串数列,然后求其中的各个范围内的第k大数

分析:划分树,具体分析见划分树算法。跟之前做过2104相比,这道题好象没有重复的元素。

代码:

View Code
  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <cstring>
  4 #include <algorithm>
  5 using namespace std;
  6 //14256K 1813MS
  7 //划分树
  8 const int maxnum=100001;
  9 struct tree
 10 {
 11     int array[maxnum];
 12     int sum[maxnum];
 13 }tree[20];
 14 int sorted[maxnum];
 15 
 16 void build_tree(int cur,int l,int r)
 17 {
 18     if(l==r)
 19         return ;
 20     int i;
 21     int m=(l+r)>>1;
 22     int lsame=m-l+1;//?
 23     for(i=l;i<=r;i++)
 24         if(tree[cur].array[i]<sorted[m])
 25             lsame--;
 26 
 27     int lnum=l,rnum=m+1;
 28     for(i=l;i<=r;i++)
 29     {
 30         if(i==l)
 31             tree[cur].sum[i]=0;
 32         else
 33             tree[cur].sum[i]=tree[cur].sum[i-1];
 34         if(tree[cur].array[i]<sorted[m])
 35         {
 36             tree[cur].sum[i]++;
 37             tree[cur+1].array[lnum++]=tree[cur].array[i];
 38         }
 39         else if(tree[cur].array[i]>sorted[m])
 40             tree[cur+1].array[rnum++]=tree[cur].array[i];
 41         else
 42         {
 43             if(lsame>0)
 44             {
 45                 lsame--;
 46                 tree[cur].sum[i]++; //?
 47                 tree[cur+1].array[lnum++]=tree[cur].array[i];
 48             }
 49             else
 50                 tree[cur+1].array[rnum++]=tree[cur].array[i];
 51         }
 52     }
 53     build_tree(cur+1,l,m);
 54     build_tree(cur+1,m+1,r);
 55 }
 56 
 57 int find(int cur,int st,int ed,int l,int r,int k)
 58 {
 59     if(l==r)
 60         return tree[cur].array[l];
 61     int lnum,rnum;
 62     int m=(st+ed)>>1;
 63     if(l-1<st)
 64         lnum=0;
 65     else
 66         lnum=tree[cur].sum[l-1];
 67     rnum=tree[cur].sum[r];
 68     if(rnum-lnum>=k)
 69         return find(cur+1,st,m,st+lnum,st+rnum-1,k);
 70     else
 71         return find(cur+1,m+1,ed,m+1+l-st-lnum,m+1+r-st-rnum,k-(rnum-lnum));
 72 }
 73 
 74 int main()
 75 {
 76     int n,m,i;
 77     scanf("%d%d",&n,&m);
 78     for(i=1;i<=n;i++)
 79     {
 80         scanf("%d",&tree[0].array[i]);
 81         sorted[i]=tree[0].array[i];
 82     }
 83     sort(sorted+1,sorted+1+n);
 84     build_tree(0,1,n);
 85 
 86     int p,r,k;
 87     while(m--)
 88     {
 89         scanf("%d%d%d",&p,&r,&k);
 90         printf("%d\n",find(0,1,n,p,r,k));
 91     }
 92     return 0;
 93 }
 94 
 95 /*
 96 7 2
 97 1 5 2 6 3 7 4
 98 1 5 3
 99 2 7 1
100 */

 

posted @ 2012-08-28 17:03  pushing my way  阅读(422)  评论(0编辑  收藏  举报