转载请注明出处,谢谢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; }