链接:http://poj.org/problem?id=2828
题意:车站有n个人在排队订票,下面n行代表第n个人,每行pos、val,val表示该人所带钱,pos表示排在该人前面比该人钱多的人的数量。输出排队的序列。
线段树解之。
#include<stdio.h>
#include<string.h>
struct aa
{
int l,r,len;
}tree[202000*3];
int num[200030];
int val[200030];
int pai[200030];
void buildtree(int le,int ri,int v)
{
int p,q;
tree[v].l=le;
tree[v].r=ri;
tree[v].len=ri-le+1;
if(le>=ri)
return ;
p=(ri+le)/2;
q=v*2;
buildtree(le,p,q);
buildtree(p+1,ri,q+1);
}
int fun(int v,int len)
{
int i,j;
i=v*2;
tree[v].len--;
if(tree[v].l==tree[v].r)
return tree[v].l;
if(tree[i].len>=len)
return fun(i,len);
else
return fun(i+1,len-tree[i].len);
}
int main()
{
int i,j,n,m;
while(scanf("%d",&n)>0) //这里如果换成while(scanf("%d",&n)>0,n)就会超时,坑爹的tle了n遍原来是这个,n惹的祸
{
for(i=1;i<=n;i++)
scanf("%d%d",&num[i],&val[i]);
buildtree(1,n,1);
for(i=n;i>=1;i--)
pai[fun(1,num[i]+1)]=val[i];
for(i=1;i<=n;i++)
{
if(i!=n)
printf("%d ",pai[i]);
else
printf("%d\n",pai[i]);
}
}
return 0;
}