POJ2182 Lost Cows(线段树)

线段树找第K大数,每个结点记录下面还没有找过的数的数目len,当查找第K大数的时候,看它左子树的len值是否大于K,如果大于说明左子树能够容纳K个数,否则在它的右子树上找K-左子树的len大数。
#include<stdio.h>
struct node
{
        int l,r;
        int len;
}tree[4*8080];
int d1[8080];
int ans[8080];
void build_tree(int p,int a,int b)
{
        tree[p].l=a;
        tree[p].r=b;
        tree[p].len=b-a+1;
        if (a==b)
        {
                return;
        }
        else
        {
                int w=p<<1;
                int mid=(a+b)>>1;
                build_tree(w,a,mid);
                build_tree(w+1,mid+1,b);
        }
}

int qurey(int p,int k)
{
        tree[p].len--;
        if (tree[p].l==tree[p].r)
                return tree[p].l;
        int w=p<<1;
        if (tree[w].len>=k)
        {
                return qurey(w,k);
        }
        else
        {
                return qurey(w+1,k-tree[w].len);
        }
}
int main()
{
        int n;
        int i;
        scanf("%d",&n);
        build_tree(1,1,n);
        for (i=1;i<n;i++)
        {
                scanf("%d",d1+i);
                d1[i]++;
        }
        d1[0]=1;
        for (i=n-1;i>=0;i--)
        {
                ans[i]=qurey(1,d1[i]);
        }
        for (i=0;i<n;i++)
        {
                printf("%d\n",ans[i]);
        }
        return 0;
}

你可能感兴趣的:(职场,休闲,poj2182,第K大数,线段数)