Codeforces Beta Round #43 (ACM-ICPC Rules), problem: (D) Parking Lot 线段树 区间合并

来源:互联网 发布:数据库中删除重复数据 编辑:程序博客网 时间:2024/05/16 12:57

题意:停车位问题。当车主想选择的空位后端有车时,车主选车位是要保证和后边的车的距离不小于b,前端有车是,保证与前面车的距离不小于f。

做法:区间合并好题啊,有很多坑等我去跳。首先是要车子离开时,后边的那个序号表示的是车子到来的时刻(这里姑且表示为那辆车子是在下第i个命令的时候来的),

然后b,f的限制是车主选车的时候人为加上的,也就是说当车子停在某个位置,它与后面的车子的距离为b,然后b<f,后边那辆车的f无法满足了,这个时候也是正确的,因为b,f只是车主停车时的顾忌,停完了车,他就不管了。还有update的时候,覆盖的位置,长度,都是车尾的实际位置,车子的实际长度。

#include<cstdio>#include<cstring>#define eps 1e8#define left l,m,x<<1#define right m+1,r,x<<1|1const int LMT=100003;int lsum[LMT<<2],rsum[LMT<<2],msum[LMT<<2],l,b,f;struct car{    int len,pos;}ca[105];inline int max(int a,int b){    return a>b?a:b;}void build(int l,int r,int x){    lsum[x]=rsum[x]=msum[x]=r+1-l;    if(l==r)return;    int m=(l+r)>>1;    build(left);    build(right);}void pushup(int x,int l,int r){    int m=(l+r)>>1;    lsum[x]=lsum[x<<1];    rsum[x]=rsum[x<<1|1];    if(lsum[x]==m+1-l)        lsum[x]+=lsum[x<<1|1];    if(rsum[x]==r-m)rsum[x]+=rsum[x<<1];    msum[x]=max(rsum[x<<1]+lsum[x<<1|1],max(msum[x<<1],msum[x<<1|1]));}int query(int len,int l,int r,int x){    if(l==r)return l;    int m=(l+r)>>1;    if(len<=msum[x<<1])return query(len,left);    if(rsum[x<<1]+lsum[x<<1|1]>=len)return m+1-rsum[x<<1];    return query(len,right);}void update(int op,int L,int R,int l,int r,int x){    if(L<=l&&r<=R)    {        msum[x]=lsum[x]=rsum[x]=op*(r+1-l);        return;    }    int m=(l+r)>>1;    if(L<=m)update(op,L,R,left);    if(R>m)update(op,L,R,right);    pushup(x,l,r);}int main(void){    int m,len,x,ord,y,cnt=0;    scanf("%d%d%d",&l,&b,&f);    build(0,l-1,1);    scanf("%d",&m);    while(m--)    {        scanf("%d",&ord);        if(ord==2)        {            scanf("%d",&x);            x--;            update(1,ca[x].pos,ca[x].pos+ca[x].len-1,0,l-1,1);            cnt++;        }        else        {           scanf("%d",&len);           if(msum[1]==l&&len<=msum[1])           {               puts("0");               ca[cnt].pos=0;               ca[cnt].len=len;               cnt++;               update(0,0,len-1,0,l-1,1);                continue;           }            if(lsum[1]>=len+f)           {               puts("0");               ca[cnt].pos=0;               ca[cnt].len=len;               cnt++;               update(0,0,len-1,0,l-1,1);               continue;           }           x=y=eps;           if(msum[1]>=len+b+f)x=query(len+b+f,0,l-1,1);           if(rsum[1]>=len+b)y=l-rsum[1];           if(x==y&&y==eps)           {               cnt++;            puts("-1");            continue;           }           if(x<y)           {               ca[cnt].len=len;               ca[cnt].pos=x+b;               cnt++;            printf("%d\n",x+b);            update(0,x+b,x+len+b-1,0,l-1,1);           }          else          {              ca[cnt].len=len;              ca[cnt].pos=y+b;              cnt++;            printf("%d\n",y+b);            update(0,y+b,y+len+b-1,0,l-1,1);          }        }    }    return 0;}