线段树找第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;
}
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;
}
转载于:https://blog.51cto.com/chenqiangjsj/415760