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++ ,