当前位置:编程学习 > C/C++ >>

CF 135 E.Parking Lot(线段树)

题目:给出1-n个停车场,陆续有车子进来 ,每次选择一个位置,要求这个位置距离两边最近的车子的距离要最远,如果有相同的位置,取标号最小的。
和POJ 的hotel类似,记录区间的最大间隔,以及左端点的最大间隔,右端点的最大间隔。以及最大间隔的起始点
其中更新部分较为复杂,这里Debug了我两个小时,泪奔。。。
由于 题目要求取标号最小的,所以这里的判断顺序不可以乱,严格从左到右的顺序。
对于区间的最大间隔,可能是从左端点开始,这样的起始是最小的,所以要最早判断
接下来可能是左区间的最大间隔
然后是左区间的右间隔与右区间的左间隔的并
然后是右区间的最大间隔
最后是右端点。
开始凭感觉,随便YY了,然后Debug了两个小时,如果出现间隔相同的,按以上顺序才能保证标号最小。
[cpp]
#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; 
                    } 
              &nbs
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,