hdu 2665 Kth number(划分树)

http://acm.tju.edu.cn/toj/showp2722.html 同样的题目

#include <stdio.h>
#include <algorithm>

 

using namespace std;

#define MAXN 100005
#define MAXLOG 20

int sorted[MAXN],seq[MAXLOG][MAXN],toleft[MAXLOG][MAXN];

struct STNode
{
    int l,r;
};
STNode node[MAXN*3];

void build(int l,int r,int idx,int d)
{
    node[idx].l=l;
    node[idx].r=r;
    if(l==r) return;
    int mid=(l+r)/2,lsame,i;
    lsame=mid-l+1;
    for(i=l;i<=r;i++)
        if(seq[d][i] < sorted[mid]) lsame--;
    int lpos=l,rpos=mid+1;
    for(i=l;i<=r;i++)
    {
        if(i==l) toleft[d][i] = 0;
        else toleft[d][i] = toleft[d][i-1];

        if(seq[d][i] < sorted[mid])
        {
            toleft[d][i]++;
            seq[d+1][lpos++] = seq[d][i];
        }
        else if(seq[d][i] > sorted[mid])
        {
            seq[d+1][rpos++] = seq[d][i];
        }
        else
        {
            if(lsame > 0)
            {
                lsame--;
                toleft[d][i]++;
                seq[d+1][lpos++] = seq[d][i];
            }
            else seq[d+1][rpos++] = seq[d][i];
        }
    }
    build(l,mid,idx*2,d+1);
    build(mid+1,r,idx*2+1,d+1);
}

int query(int l,int r,int k,int idx,int d)
{
 //   printf("(%d,%d,%d,%d,%d)\n",l,r,k,idx,d);
    if(l==r) return seq[d][l];
    int ss,s,newl,newr;//s表示[ l , r ]有多少个分到左边,ss表示 [node[idx].l , l-1 ]有多少个分到左边
    ss = (l==node[idx].l) ? 0 : toleft[d][l-1];
    s = toleft[d][r] - ss;
    if(s >= k)
    {
        newl = node[idx].l + ss;
        newr = newl + s - 1;
        return query(newl,newr,k,idx*2,d+1);
    }
    else
    {
        int bb = l - node[idx].l - ss;; //bb表示 [node[idx].l , l-1 ]有多少个分到右边
        int b = r - l + 1 - s; //b表示 [l , r]有多少个分到右边
        newl = node[idx*2+1].l + bb;
        newr = newl + b - 1;
        return query(newl,newr,k-s,idx*2+1,d+1);
    }
}

void showtree(int idx,int d)
{
    printf("(%d,%d) ",node[idx].l,node[idx].r);
    for(int i=node[idx].l;i<=node[idx].r;i++)printf("%d ",seq[d][i]);printf("\n");
    if(node[idx].l==node[idx].r) return;
    showtree(idx*2,d+1);
    showtree(idx*2+1,d+1);
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("tdata.txt","r",stdin);
    #endif
    int T,i,j,k,n,q;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&n,&q);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&sorted[i]);
            seq[1][i]=sorted[i];
        }
        sort(sorted+1,sorted+n+1);
        build(1,n,1,1);
        while(q--)
        {
            scanf("%d %d %d",&i,&j,&k);
            int ans = query(i,j,k,1,1);
            printf("%d\n",ans);
        }
    }
    return 0;
}

posted @ 2010-09-05 10:59  菜到不得鸟  阅读(304)  评论(0)    收藏  举报