题目;http://acm.hdu.edu.cn/showproblem.php?pid=5493
题目大意,t组数据,n个人,n行每行分别是人的身高和这个人的左边或右边比他高的人的个数,输出符合条件的字典序最小的人排列的序列.
想到线段树就很好做了,记录空位,按顺序安放人的身高,和原来做的题目很相似
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 struct point { 5 int h,k; 6 bool operator <(const point & a)const 7 { 8 return h<a.h; 9 } 10 }; 11 point yj[100001]; 12 int res[100001]; 13 struct node{ 14 int l,r,x; 15 }; 16 node tree[100001*4]; 17 void build(int i,int left,int right) 18 { 19 tree[i].l=left;tree[i].r=right; 20 if (left==right) 21 { 22 tree[i].x=1; 23 return ; 24 } 25 int mid=(left+right)>>1; 26 build(i<<1,left,mid); 27 build(i<<1|1,mid+1,right); 28 tree[i].x=tree[i<<1].x+tree[i<<1|1].x; 29 } 30 void update(int i,int ans,int num) 31 { 32 if (tree[i].l==tree[i].r) 33 { 34 tree[i].x=0; 35 res[tree[i].l]=num; 36 return ; 37 } 38 int mid=(tree[i].l+tree[i].r)>>1; 39 if (ans<=tree[i<<1].x) update(i<<1,ans,num); 40 else update(i<<1|1,ans-tree[i<<1].x,num); 41 tree[i].x=tree[i<<1].x+tree[i<<1|1].x; 42 } 43 int main() 44 { 45 int t,i,q=1,n; 46 scanf("%d",&t); 47 while (t--) 48 { 49 scanf("%d",&n); 50 for (i=1;i<=n;i++) 51 scanf("%d %d",&yj[i].h,&yj[i].k); 52 sort(yj+1,yj+n+1); 53 build(1,1,n); 54 int flag=0; 55 for (i=1;i<=n;i++) 56 { 57 int m=n-i; 58 int temp=m-yj[i].k; 59 if (temp<0) 60 { 61 flag=1; 62 break; 63 } 64 if (temp>yj[i].k) update(1,yj[i].k+1,yj[i].h); 65 else update(1,temp+1,yj[i].h); 66 } 67 printf("Case #%d: ",q++); 68 if (flag) printf("impossible\n"); 69 else 70 { 71 for (i=1;i<=n;i++) 72 { 73 if (i!=n) printf("%d ",res[i]); 74 else printf("%d\n",res[i]); 75 } 76 } 77 } 78 return 0; 79 }