【线段树】HDU 5493 Queue (2015 ACM/ICPC Asia Regional Hefei Online)

题目链接:

  http://acm.hdu.edu.cn/showproblem.php?pid=5493

题目大意:

  N个人,每个人有一个唯一的高度h,还有一个排名r,表示它前面或后面比它高的人的个数,求按身高字典序最小同时满足排名的身高排列。

题目思路:

  【线段树】

  首先可以知道,一个人前面或后面有r个人比他高,那么他是第r+1高或第n-i-r+1高,i为这个人是第几高的。

  所以先将人按照身高从小到大排序,接下来,把当前这个人放在第k=min(r+1,n-i-r+1)高的位置。

  用线段树维护包含当前这个位置之前有多少个空,因为身高是递增的,所以前面已经放的都比当前这个人矮,而空的位置都将比这个人高,所以把这个人放在第k个空位置即可。

  1 //
  2 //by coolxxx
  3 //#include<bits/stdc++.h>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<string>
  7 #include<iomanip>
  8 #include<map>
  9 #include<stack>
 10 #include<queue>
 11 #include<set>
 12 #include<bitset>
 13 #include<memory.h>
 14 #include<time.h>
 15 #include<stdio.h>
 16 #include<stdlib.h>
 17 #include<string.h>
 18 //#include<stdbool.h>
 19 #include<math.h>
 20 #define min(a,b) ((a)<(b)?(a):(b))
 21 #define max(a,b) ((a)>(b)?(a):(b))
 22 #define abs(a) ((a)>0?(a):(-(a)))
 23 #define lowbit(a) (a&(-a))
 24 #define sqr(a) ((a)*(a))
 25 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
 26 #define mem(a,b) memset(a,b,sizeof(a))
 27 #define eps (1e-8)
 28 #define J 10000
 29 #define mod 1000000007
 30 #define MAX 0x7f7f7f7f
 31 #define PI 3.14159265358979323
 32 #define N 100004
 33 using namespace std;
 34 typedef long long LL;
 35 int cas,cass;
 36 int n,m,lll,ans;
 37 LL aans;
 38 int s[N<<2],t[N];
 39 struct xxx
 40 {
 41     int h,r;
 42 }a[N];
 43 bool cmp(xxx aa,xxx bb)
 44 {
 45     return aa.h<bb.h;
 46 }
 47 void build(int l,int r,int k)
 48 {
 49     if(l==r){s[k]=1;return;}
 50     if(l>r)return;
 51     int mid=(l+r)>>1;
 52     build(l,mid,k+k);
 53     build(mid+1,r,k+k+1);
 54     s[k]=s[k+k]+s[k+k+1];
 55 }
 56 void change(int l,int r,int pos,int x,int k)
 57 {
 58     if(l==r){t[l]=x,s[k]=0;return;}
 59     if(l>r)return;
 60     int mid=(l+r)>>1;
 61     if(pos<=s[k+k])change(l,mid,pos,x,k+k);
 62     else change(mid+1,r,pos-s[k+k],x,k+k+1);
 63     s[k]=s[k+k]+s[k+k+1];
 64 }
 65 int main()
 66 {
 67     #ifndef ONLINE_JUDGE
 68 //    freopen("1.txt","r",stdin);
 69 //    freopen("2.txt","w",stdout);
 70     #endif
 71     int i,j,k;
 72 
 73 //    for(scanf("%d",&cass);cass;cass--)
 74     for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
 75 //    while(~scanf("%s",s+1))
 76 //    while(~scanf("%d",&n))
 77     {
 78         printf("Case #%d: ",cass);
 79         scanf("%d",&n);
 80         for(i=1;i<=n;i++)
 81             scanf("%d%d",&a[i].h,&a[i].r);
 82         sort(a+1,a+1+n,cmp);
 83         build(1,n,1);
 84         for(i=1;i<=n;i++)
 85         {
 86             j=min(a[i].r,n-i-a[i].r);
 87             if(j<0)break;
 88             change(1,n,j+1,a[i].h,1);
 89         }
 90         if(i<=n){puts("impossible");continue;}
 91         for(i=1;i<=n;i++)
 92             printf("%d%c",t[i],(i==n)?'
':' ');
 93     }
 94     return 0;
 95 }
 96 /*
 97 //
 98 
 99 //
100 */
View Code
原文地址:https://www.cnblogs.com/Coolxxx/p/5831841.html