CF 135 E.Parking Lot(线段树)

来源:互联网 发布:辗转相除法c语言 编辑:程序博客网 时间:2024/06/05 03:26

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove

题目:给出1-n个停车场,陆续有车子进来 ,每次选择一个位置,要求这个位置距离两边最近的车子的距离要最远,如果有相同的位置,取标号最小的。

和POJ 的hotel类似,记录区间的最大间隔,以及左端点的最大间隔,右端点的最大间隔。以及最大间隔的起始点

其中更新部分较为复杂,这里Debug了我两个小时,泪奔。。。

由于 题目要求取标号最小的,所以这里的判断顺序不可以乱,严格从左到右的顺序。

对于区间的最大间隔,可能是从左端点开始,这样的起始是最小的,所以要最早判断

接下来可能是左区间的最大间隔

然后是左区间的右间隔与右区间的左间隔的并

然后是右区间的最大间隔

最后是右端点。

开始凭感觉,随便YY了,然后Debug了两个小时,如果出现间隔相同的,按以上顺序才能保证标号最小。

#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#define eps 1e-10#define N 200005#define inf 1<<20#define zero(a) (fabs(a)<eps)#define lson (step<<1)#define rson (step<<1|1)using namespace std;struct Node{    int left,right,mid;    int mx,lx,rx,val;    int dist(){return right-left+1;}}L[N*4];int pos[1000005];void Bulid(int step,int l,int r){    L[step].left=l;    L[step].right=r;    L[step].mid=(l+r)/2;    L[step].mx=L[step].rx=L[step].lx=L[step].dist();    L[step].val=l;    if(l==r)       return ;    Bulid(lson,l,L[step].mid);    Bulid(rson,L[step].mid+1,r);}void Push_Up(int step){    L[step].lx=L[lson].lx+(L[lson].lx==L[lson].dist()?L[rson].lx:0);    L[step].rx=L[rson].rx+(L[rson].rx==L[rson].dist()?L[lson].rx:0);    //初始化为最左区间    L[step].mx=L[step].lx;L[step].val=L[step].left;    //左区间的最大间隔    if(L[lson].mx>L[step].mx+1||(L[lson].mx>L[step].mx&&L[step].mx%2==0)){        L[step].mx=L[lson].mx;        L[step].val=L[lson].val;    }    //左区间的右端与右区间左端的并    if(L[lson].rx+L[rson].lx>L[step].mx+1||(L[lson].rx+L[rson].lx>L[step].mx&&L[step].mx%2==0)){        L[step].mx=L[lson].rx+L[rson].lx;        L[step].val=L[lson].right-L[lson].rx+1;    }    //右区间的最大间隔    if(L[rson].mx>L[step].mx+1||(L[rson].mx>L[step].mx&&L[step].mx%2==0)){        L[step].mx=L[rson].mx;        L[step].val=L[rson].val;    }    //右端点    if(L[step].rx>L[step].mx+1||(L[step].rx>L[step].mx&&L[step].mx%2==0)){        L[step].mx=L[step].rx;        L[step].val=L[step].right-L[step].rx+1;    }}void update(int step,int p,int k){    if(L[step].left==L[step].right){        //K为1表示停入一辆车        if(k){            L[step].mx=L[step].rx=L[step].lx=0;            L[step].val=N;        }        else{            L[step].mx=L[step].rx=L[step].lx=1;            L[step].val=L[step].left;        }        return ;    }    if(p<=L[step].mid) update(lson,p,k);    else update(rson,p,k);    Push_Up(step);}int main(){    int n,q;  //  freopen("1.in","r",stdin); //  freopen("1.out","w",stdout);    while(scanf("%d%d",&n,&q)!=EOF){        Bulid(1,1,n);        int cnt=1;        while(q--){            int ope,id;            scanf("%d%d",&ope,&id);            if(ope==2)   update(1,pos[id],0);            else{                int len=L[1].mx,val=L[1].val,ret;                //如果最长的区间是连着右端点,需要特殊考虑                if(val+len-1==n){                    if(val==1) ret=1;                    else ret=n;                }                else{                    ret=1;                //特殊考虑左端点                    int mmax=L[1].lx-1;   //如果放在左端点时的间隔                    //考虑最长的区间                    if((len-1)/2>mmax){                        mmax=(len-1)/2;                        ret=val+(len-1)/2;                    }                    //考虑右端点                    if(L[1].rx-1>mmax){                        mmax=L[1].rx-1;                        ret=n;                    }                }                printf("%d\n",ret);                pos[id]=ret;                update(1,ret,1);            }        }    }    return 0;}






原创粉丝点击