停车场

来源:互联网 发布:如何做好美工 编辑:程序博客网 时间:2024/04/25 21:04

题目描述
刚拿到驾照的 KJ 总喜欢开着车到处兜风,玩完了再把车停到阿 Q 的停车场里,虽然她对自己停车的水平很有信心,但她还是不放心其他人的停车水平,尤其是 Kelukin。于是,她每次都把自己的爱车停在距离其它车最远的一个车位。KJ 觉得自己这样的策略非常科学,于是她开始想:在一个停车场中有一排车位,从左到右编号为 1 到 n,初始时全部是
空的。有若干汽车,进出停车场共 m 次。对于每辆进入停车场的汽车,会选择与其它车距离最小值最大的一个车位,若有多个符合条件,选择最左边一个。KJ 想着想着就睡着了,在她一旁的 Kelukin 想帮她完成这个心愿,但是他又非常的懒,不愿意自己动手,于是就把这个问题就留给了你:在 KJ 理想的阿 Q 的停车场中,给你车辆进出的操作序列,依次输
出每辆车的车位编号。

输入
第一行,两个整数 n 和 m,表示停车场大小和操作数;
接下来 m 行,每行两个整数 F 和 x
F 是 1 表示编号为 x 的车进停车场;
F 是 2 表示编号为 x 的车出停车场;
保证操作合法,即:
出停车场的车一定目前仍在停车场里;
停车场内的车不会超过 n;

输出
对于所有操作 1,输出一个整数,表示该车车位的编号

样例输入
7 11
1 15
1 123123
1 3
1 5
2 123123
2 15
1 21
2 3
1 6
1 7
1 8

样例输出
1
7
4
2
7
4
1
3

  • 翻译一下题目,就是叫你把一个[1,n]的区间每次找到“最长”的那一段,输出那段的中间点(停车的位置),特殊判断[1,p]:停车在1 和 [q,n]:停车在n.
  • 方法一:用线段树做,每次停车,将停车位置上的权值视为0,每次开走,将停车位置上的权值视为1. 用上传更新(我这样叫它:push_pu())的方法更新每段区间内的最长线段mx和最长线段的起始位置mxpos。为了更新最长线段,需要记录区间左端开始的最长线段lmx和右段开始的最长线段rmx。就像hotel那道题一样。特殊的是,最长线段mx不必再包含区间两端的lmx和rmx,因为并没什么用。最后Quary的时候要特殊判断。
  • 方法二:用优先队列做,把停车后截成的小线段进队列,判断当前的最大线段是否合理用树状数组。在用链表记录一下车左右的车的位置,就差不多了。
#include<cstdio>#define MAXN 200000#define MAXNUM 2000000struct node{    int l,r;    int lmx,rmx,mx,mxpos;}tree[MAXN*4+100];int n,m,car[MAXNUM+10];void build(int i,int l,int r){    tree[i].l=l,tree[i].r=r;    tree[i].lmx=tree[i].rmx=tree[i].mx=r-l+1;    tree[i].mxpos=l;    if(l==r) return ;    int mid=(l+r)/2;    build(i*2,l,mid);    build(i*2+1,mid+1,r);}int Weight(int len){    if(!len) return 0;    return (len-1)/2+1;}void Adjust(int i,int len,int st){    if(!len) return ;    int g=Weight(tree[i].mx),h=Weight(len);    if(g<h) tree[i].mx=len,tree[i].mxpos=st;    else if(g==h && st<tree[i].mxpos) tree[i].mxpos=st;}void push_up(int i){    tree[i].lmx=tree[i*2].lmx,tree[i].rmx=tree[i*2+1].rmx;    if(tree[i].lmx==tree[i*2].r-tree[i*2].l+1)        tree[i].lmx+=tree[i*2+1].lmx;    if(tree[i].rmx==tree[i*2+1].r-tree[i*2+1].l+1)        tree[i].rmx+=tree[i*2].rmx;    //标记好mx=0,impossible;mx不用一并包含lmx和rmx    tree[i].mxpos=0,tree[i].mx=0;    Adjust(i,tree[i*2].rmx+tree[i*2+1].lmx,tree[i*2].r-tree[i*2].rmx+1);    Adjust(i,tree[i*2].mx,tree[i*2].mxpos);    Adjust(i,tree[i*2+1].mx,tree[i*2+1].mxpos);}void insert(int i,int inpos,int d){    if(tree[i].l==inpos && tree[i].r==inpos){        tree[i].lmx=tree[i].rmx=tree[i].mx=d;        if(d)            tree[i].mxpos=tree[i].l;        else            tree[i].mxpos=0;        return ;    }    int mid=(tree[i].l+tree[i].r)/2;    if(inpos<=mid) insert(i*2,inpos,d);    else insert(i*2+1,inpos,d);    push_up(i);}int Quary(){    int len=(tree[1].mx-1)/2+1,ret=(tree[1].mxpos*2+tree[1].mx-1)/2;    if(tree[1].lmx>=len) ret=1;    else if(tree[1].rmx>len) ret=n;    return ret;}int main(){    int p,num,inpos;    scanf("%d%d",&n,&m);    build(1,1,n);    for(int i=1;i<=m;i++){        scanf("%d%d",&p,&num);        if(p==1){            inpos=Quary();            printf("%d\n",inpos);            car[num]=inpos;            insert(1,inpos,0);        }        else{            inpos=car[num];            insert(1,inpos,1);            car[num]=0;        }    }}

错误代码:还不知道怎么错了!!!!!!!!

#include<cstdio>#define MAXN 200000#define MAXNUM 2000000struct node{    int l,r;    int lmax,rmax,maxx,mxpos;}tree[MAXN*4+100];int n,m,car[MAXNUM+10];void build(int i,int l,int r){    tree[i].l=l,tree[i].r=r;    tree[i].lmax=tree[i].rmax=tree[i].maxx=r-l+1;    tree[i].mxpos=l;    if(l==r) return ;    int mid=(l+r)/2;    build(i*2,l,mid);    build(i*2+1,mid+1,r);}void revise(int i,int len,int pos){    tree[i].lmax=tree[i].rmax=tree[i].maxx=len;    tree[i].mxpos=pos;}int Interval(node a){    return a.r-a.l+1;}int Weight(int l,int len){    if(!len) return -1;    if(l==1) return len;    if(l+len-1==n) return len;    return (len-1)/2+1;}void Adjust(int i,int tmp,int tmpl){    int a=Weight(tree[i].mxpos,tree[i].maxx),b=Weight(tmpl,tmp);    if(a<b)        tree[i].maxx=tmp,tree[i].mxpos=tmpl;    else if(a==b && tree[i].mxpos>tmpl)        tree[i].mxpos=tmpl;}void insert(int i,int inpos,int d){    if(tree[i].l==inpos && tree[i].r==inpos){        if(d) revise(i,1,tree[i].l);        else revise(i,0,0);        return ;    }    int mid=(tree[i].l+tree[i].r)/2;    if(inpos<=mid) insert(i*2,inpos,d);    else insert(i*2+1,inpos,d);    tree[i].lmax=tree[i*2].lmax,tree[i].rmax=tree[i*2+1].rmax;    if(tree[i].lmax==Interval(tree[i*2]))        tree[i].lmax+=tree[i*2+1].lmax;    if(tree[i].rmax==Interval(tree[i*2+1]))        tree[i].rmax+=tree[i*2].rmax;    tree[i].maxx=tree[i].lmax;    tree[i].mxpos=tree[i].l;    Adjust(i,tree[i].rmax,tree[i].r-tree[i].rmax+1);    Adjust(i,tree[i*2].rmax+tree[i*2+1].lmax,tree[i*2].r-tree[i*2].rmax+1);    Adjust(i,tree[i*2].maxx,tree[i*2].mxpos);    Adjust(i,tree[i*2+1].maxx,tree[i*2+1].mxpos);}int Quary(){    int len=(tree[1].maxx-1)/2+1,ret=(tree[1].mxpos*2+tree[1].maxx-1)/2;    if(tree[1].lmax>=len) len=tree[1].lmax,ret=1;    if(tree[1].rmax>len) ret=n;    return ret;}int main(){    int p,num;    scanf("%d%d",&n,&m);    build(1,1,n);    for(int i=1;i<=m;i++){        scanf("%d%d",&p,&num);        if(p==1){            int pos=Quary();            printf("%d\n",pos);            car[num]=pos;            insert(1,pos,0);        }        else{            int pos=car[num];            insert(1,pos,1);            car[num]=0;        }    }}
0 0