POJ 2104 K-th Number(划分树)

来源:互联网 发布:阿里云事业部组织架构 编辑:程序博客网 时间:2024/05/24 03:01

题目链接:http://poj.org/problem?id=2104

给定数组,和任意区间,求这个区间内第K大数

划分树的典型题

划分树具体讲解我是看http://shizhixinghuo.diandian.com/post/2012-09-02/40037691896

#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;const int maxn = 110000;int rec[maxn];struct node{    int left;    int right;    int mid;}tree[maxn*5];struct point{    int value;    int right;    bool is_right;}po[20][maxn];int n,m;int build_tree(int left,int right,int deepth,int pos){    tree[pos].left=left;    tree[pos].right=right;    tree[pos].mid=(left+right)>>1;    int mid=rec[tree[pos].mid],l=left,r=tree[pos].mid+1,i,j,k;    point *now=po[deepth-1],*then=po[deepth];    for(i=left;i<=right;i++){        if(now[i].value>mid){            then[r++].value=now[i].value;            now[i].is_right=true;        }else{            then[l++].value=now[i].value;            now[i].is_right=false;        }    }    now[left].right=now[left].is_right;    for(i=left+1;i<=right;i++){        now[i].right=now[i-1].right+now[i].is_right;    }    if(left == right) return 0;    build_tree(left,tree[pos].mid,deepth+1,pos<<1);    build_tree(tree[pos].mid+1,right,deepth+1,(pos<<1)+1);    return 0;}int query(int left,int right,int k,int deepth,int pos){    int num=0;    point *now=po[deepth];    if(tree[pos].left == tree[pos].right) return now[tree[pos].left].value;    num=right-left+1-(now[right].right-now[left].right+now[left].is_right);    if(num>=k)    return query(left-now[left].right+now[left].is_right,right-now[right].right,k,deepth+1,pos<<1);    else    return query(tree[pos].mid+now[left].right+1-now[left].is_right,\                 tree[pos].mid+now[right].right,k-num,deepth+1,(pos<<1)+1);}int main(){    int i,j,a,b,k;    while(scanf("%d%d",&n,&m)!=EOF){        for(i=1;i<=n;i++){            scanf("%d",&rec[i]);            po[0][i].value=rec[i];        }        sort(rec+1,rec+1+n);        build_tree(1,n,1,1);        while(m--){            scanf("%d%d%d",&a,&b,&k);            printf("%d\n",query(a,b,k,0,1));        }    }    return 0;}


0 0
原创粉丝点击