Poj 2104 K-th number Solution(划分树代码)

#include <cstdio>

#include <cstdlib>

#include <cstring>



using namespace std;



#define MAXN 100001

#define MAXD 100



struct node {

    node *left_child,*right_child;
    int l,r;
    int MID,mid;
    int depth;
    bool flag0;

};



node *roof;

int a[MAXD][MAXN];

int f[MAXD][MAXN];

int n,m;



int get_random(int l,int r){

    int x=0;
    for (int i=0;i++<5;){
        x+=rand();
    }
    x%=(r-l+1);
    x+=l;
    return x;

}





int get_f(int x,node *p){
    if (x<(*p).l){
        return 0;
    }
    return f[(*p).depth][x];

}



//建树

int Build(int l,int r,int depth,node *p){
    (*p).l=l;
    (*p).r=r;
    (*p).depth=depth;
    (*p).flag0=false;
    if (l==r){
        (*p).MID=a[depth][l];
        (*p).mid=l;
        return 0;
    }
    bool flag=true;
    for (int i=l;i++<r;){
        if (a[depth][i]!=a[depth][i-1]){
            flag=false;
            break;
        }
    }
    if (flag){
        (*p).flag0=true;
        (*p).MID=a[depth][l];
        return 0;
    }
    while (1){
        (*p).MID=a[depth][get_random(l,r)];
        (*p).mid=l;
        for (int i=l;i<=r;i++){
            if (a[depth][i]<=(*p).MID){
                a[depth+1][(*p).mid++]=a[depth][i];
                f[depth][i]=get_f(i-1,p)+1;
            } else {
                f[depth][i]=get_f(i-1,p);
            }
        }
        int j=((*p).mid--);
        if ((*p).mid>=r){
            continue;
        }
        for (int i=l;i<=r;i++){
            if (a[depth][i]>(*p).MID){
                a[depth+1][j++]=a[depth][i];
            }
        }
        break;
    }
    Build(l,(*p).mid,depth+1,(*p).left_child=new(node));
    Build((*p).mid+1,r,depth+1,(*p).right_child=new(node));
    return 0;

}



//查询

int find(int l,int r,int k,node *p){
    if ((*p).l==(*p).r||(*p).flag0){
        return (*p).MID;
    }
    if ((*p).flag0){
        return a[(*p).depth][l+k-1];
    }
    int left_s=get_f(r,p)-get_f(l-1,p);
    int right_s=(r-l+1)-left_s;
    int left_=(*p).l+get_f(l-1,p);
    int right_=(*p).mid+(l-(*p).l)-get_f(l-1,p)+1;
    if (k<=left_s) return find(left_,left_+left_s-1,k,(*p).left_child);
    return find(right_,right_+right_s-1,k-left_s,(*p).right_child);

}





int main(){
    srand(0);
    memset(f,sizeof(f),0);
    memset(a,sizeof(a),0);
    scanf("%d%d",&n,&m);
    for (int i=0;i++<n;){
        scanf("%d",&a[0][i]);
    }
    Build(1,n,0,roof=new(node));
    while (m--){
        int l,r,k;
        scanf("%d%d%d",&l,&r,&k);
        printf("%d\n",find(l,r,k,roof));
    }
    return 0;

}
    原文作者:AmadeusChan
    原文地址: https://www.jianshu.com/p/f990f4d8f475
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞