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 */

 

你可能感兴趣的:(poj)