线段树区间维护cf46D

来源:互联网 发布:查询系统端口 编辑:程序博客网 时间:2024/05/13 13:55

D. Parking Lot

题意:0~L停车,与前面的相离发f,后面的相离b,有两种操作:

1 x表示把长度为x的停进去,尽量靠近0

2 x表示把操作编号为x的车开走

如果前面没有车则可以靠0这条边停,这样的话可以在L加上b和f然后再做,线段树维护区间连续空位,左边连续,右边连续和setv(表示当前区间的状态,是不是被占用)

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=110;const int maxm=101000;int L,b,f,n;int cars[maxn],care[maxn];struct IntervalTree{    int maxv[maxm<<3],ls[maxm<<3],rs[maxm<<3];    int setv[maxm<<3];    void build(int o,int l,int r)    {        maxv[o]=ls[o]=rs[o]=r-l+1;        setv[o]=-1;        if(l==r)return;        int mid=(l+r)>>1;        build(o<<1,l,mid);        build(o<<1|1,mid+1,r);    }    void maintain(int o,int l,int r)    {        if(setv[o]!=-1)        {            if(setv[o]==0)maxv[o]=ls[o]=rs[o]=0;            else maxv[o]=ls[o]=rs[o]=r-l+1;        }        else if(r>l)        {            maxv[o]=max(maxv[o<<1],maxv[o<<1|1]);            maxv[o]=max(maxv[o],rs[o<<1]+ls[o<<1|1]);            ls[o]=ls[o<<1];rs[o]=rs[o<<1|1];            int mid=(l+r)>>1;            if(ls[o]==mid-l+1)ls[o]+=ls[o<<1|1];            if(rs[o]==r-mid)rs[o]+=rs[o<<1];        }    }    void pushdown(int o,int l,int r)    {        if(setv[o]!=-1)        {            setv[o<<1]=setv[o<<1|1]=setv[o];            setv[o]=-1;            int mid=(l+r)>>1;        }    }    void update(int o,int l,int r,int q1,int q2,int x)    {        if(q1<=l&&r<=q2)        {            setv[o]=x;        }        else        {            int mid=(l+r)>>1;            pushdown(o,l,r);            if(q1<=mid)update(o<<1,l,mid,q1,q2,x);else maintain(o<<1,l,mid);            if(q2>mid)update(o<<1|1,mid+1,r,q1,q2,x);else maintain(o<<1|1,mid+1,r);        }        maintain(o,l,r);    }    int query(int o,int l,int r,int len)    {        if(ls[o]>=len)return l;        int mid=(l+r)>>1;        pushdown(o,l,r);        if(maxv[o<<1]>=len)return query(o<<1,l,mid,len);        else if(rs[o<<1]+ls[o<<1|1]>=len)return mid-rs[o<<1]+1;        else return query(o<<1|1,mid+1,r,len);    }}tree;int main(){    //freopen("in.txt","r",stdin);    int op,x;    scanf("%d%d%d",&L,&b,&f);    L=b+L+f-1;    tree.build(1,0,L);    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d%d",&op,&x);        if(op==1)        {            if(tree.maxv[1]>=b+x+f)            {                int pos=tree.query(1,0,L,b+x+f);                cars[i]=pos+b;care[i]=pos+b+x-1;//本来应该是靠0停,但是总长度加了b和f,所以相当于离前一个距离为b                tree.update(1,0,L,cars[i],care[i],0);                printf("%d\n",pos);            }            else printf("-1\n");        }        else tree.update(1,0,L,cars[x],care[x],1);    }    return 0;}


0 0
原创粉丝点击