cf-64d(Parking Lot)成段更新+区间合并

题目看了一个小时,想了半个小时,敲了一个小时,debug将近三个半小时。。。。。。//还是看数据的
将停车分成两个操作,先找出停车的起始点位置,然后再成段更新。
这里用线段树维护区间最多能停多长的车(包括前距和后距)
找其实点时,先判断能否放在起点,此时它要放的长度只需lth(+f也无妨),
如果可以,就找到了。
否则要放的长度需要lth+b+f(当放在末尾时,其实不需要+f,但为了方便,我们可以将区间延长b+f,然后对求出的起始点判断是否可行即可),如果求出结果可行,就以该起点到车的末尾成段更新,否则输出-1.

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <stack>
#include <vector>
#include <string.h>
#include <queue>
#define msc(X) memset(X,-1,sizeof(X))
#define ms(X) memset(X,0,sizeof(X))
typedef long long LL;
using namespace std;
const int MAXN=1e5+1050;
#define lson tn<<1,l,mid
#define rson tn<<1|1,mid+1,r
struct _Tree
{
    int len,lmax,rmax,amax,lazy;
}tree[MAXN<<2];
void PushUp(int tn)
{
    tree[tn].lmax=(tree[tn<<1].lmax==tree[tn<<1].len?
        (tree[tn<<1].len+tree[tn<<1|1].lmax):tree[tn<<1].lmax);
    tree[tn].rmax=(tree[tn<<1|1].rmax==tree[tn<<1|1].len?
        (tree[tn<<1].rmax+tree[tn<<1|1].len):tree[tn<<1|1].rmax);
    tree[tn].amax=max(tree[tn<<1].amax,tree[tn<<1|1].amax);
    tree[tn].amax=max(tree[tn].amax,tree[tn<<1].rmax+tree[tn<<1|1].lmax);   
}
void build(int tn,int l,int r)
{
    tree[tn].len=tree[tn].lmax=
    tree[tn].rmax=tree[tn].amax=r-l+1;
    tree[tn].lazy=-1;
    if(l==r) return ;
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
}
void PushDown(int tn)
{
    if(tree[tn].lazy!=-1){
        int flg=tree[tn].lazy;
        tree[tn<<1].lazy=tree[tn<<1|1].lazy=flg;
        tree[tn<<1].amax=tree[tn<<1].lmax
            =tree[tn<<1].rmax=(flg?0:tree[tn<<1].len);
        tree[tn<<1|1].amax=tree[tn<<1|1].lmax
            =tree[tn<<1|1].rmax=(flg?0:tree[tn<<1|1].len);
        tree[tn].lazy=-1;
    }
}
int query(int tn,int l,int r,int len)
{

    if(l==r) return l;
    PushDown(tn);
    int mid=(l+r)>>1;
    if(tree[tn<<1].amax>=len)
        return query(lson,len);
    else if(tree[tn<<1].rmax+tree[tn<<1|1].lmax>=len)
            return mid-tree[tn<<1].rmax+1;
    else return query(rson,len);
}
void update(int tn,int l,int r,int x,int y,int flg)
{
    if(x<=l&&r<=y){
        tree[tn].lazy=flg;
        tree[tn].amax=tree[tn].lmax
            =tree[tn].rmax=
            (flg?0:tree[tn].len);
        return;
    }
    PushDown(tn);
    int mid=(l+r)>>1;
    if(x<=mid) update(lson,x,y,flg);
    if(y>mid) update(rson,x,y,flg);
    PushUp(tn);
}
struct _Query
{
    int frm,to;
}qry[110];
int main(int argc, char const *argv[])
{
    int L,b,f;
    scanf("%d %d %d",&L,&b,&f);
    build(1,1,L+b+f);
    ms(qry);
    int q;
    scanf("%d",&q);
    for(int i=1;i<=q;i++)
    {
        int typ,lth;
        scanf("%d %d",&typ,&lth);   
        if(typ==1){
            if(lth+b+f>tree[1].amax) {puts("-1");
            continue;}
            int pos=query(1,1,L+b+f,lth+f);//特殊处理
            if(pos==1){
                pos--;
                if(pos+lth<=L){
                update(1,1,L+b+f,pos+1,pos+lth,1);
                printf("%d\n",pos );
                qry[i].frm=pos+1,
                qry[i].to=pos+lth;
                }
            }
            else {
                pos=query(1,1,L+b+f,lth+b+f);
                if(pos!=-1){
                    pos+=b-1;
                    if(pos+lth<=L){
                    update(1,1,L+b+f,pos+1,pos+lth,1);
                    printf("%d\n",pos );
                    qry[i].frm=pos+1,
                    qry[i].to=pos+lth;
                    }
                    else puts("-1");
                }
                else puts("-1");
            }
        }
        else 
         update(1,1,L+b+f,qry[lth].frm,qry[lth].to,0);
    }
    return 0;
}
/*
2 2 3
1
1 2

10 0 0
11
1 1
1 1
1 1
1 1
1 1
2 5
1 1
1 1
1 1
1 1
1 1
1 1

20 1 2
10
1 3
1 2
2 2
2 1
1 4
1 2
1 2
2 7
1 2
1 1

*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值