腐女的生日

来源:互联网 发布:社区app软件 编辑:程序博客网 时间:2024/04/30 00:10

题目描述

腐女要过生日了,pty 想给腐女送礼物,但是腐女所在的教室离pty 的教室太远了,于是pty就拜托会动归和A星的djy帮忙送礼物。djy在学校建立了一个平面直角坐标系,他站在了(0,0)点,腐女在(x0,y0)点,djy每次只能往上下左右四个方向移动一步,中间有n栋矩形教学楼,每个教学楼给出两个对角的坐标,并且保证每栋教学楼的周围区域(如图所示)不会有别的教学楼,即djy可以绕一个教学楼走不会碰到任何障碍,现在djy 想知道从起点到终点不碰到任何教学楼,最短需要多少步。

扫描线

除了第一步会左走
其余情况均不会左走。
用扫描线保存当前x坐标下到每点的最短路。
遇到矩形边界时讨论一下。

#include<cstdio>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=100000+10,mx=1000002,maxm=2000003;int sx[maxm*4+100],gc[maxm*4+100];bool bz[maxm*4+100],pd[maxm*4+100];struct dong{    int x,ca,y0,y1;} ask[maxn*2];int i,j,k,l,r,t,n,m,tot,top,x,x0,y0,x1,y1,x2,y2,ans;int read(){    int x=0,f=1;    char ch=getchar();    while (ch<'0'||ch>'9'){        if (ch=='-') f=-1;        ch=getchar();    }    while (ch>='0'&&ch<='9'){        x=x*10+ch-'0';        ch=getchar();    }    return x*f;}bool cmp(dong a,dong b){    return a.x<b.x||a.x==b.x&&a.ca>b.ca;}void markad(int p,int v,int d){    if (pd[p]) return;    sx[p]+=v;    gc[p]+=d;}void markcl(int p){    bz[p]=1;    sx[p]=gc[p]=0;}void down(int p,int l,int r){    int mid=(l+r)/2;    if (bz[p]){        markcl(p*2);        markcl(p*2+1);        bz[p]=0;    }    if (sx[p]||gc[p]){        markad(p*2,sx[p],gc[p]);        markad(p*2+1,sx[p]+(mid-l+1)*gc[p],gc[p]);        sx[p]=gc[p]=0;    }}void change(int p,int l,int r,int a,int b,int v,int d){    if (pd[p]||a>b) return;    if (l==a&&r==b){        markad(p,v,d);        return;    }    down(p,l,r);    int mid=(l+r)/2;    if (b<=mid) change(p*2,l,mid,a,b,v,d);    else if (a>mid) change(p*2+1,mid+1,r,a,b,v,d);    else{        change(p*2,l,mid,a,mid,v,d);        change(p*2+1,mid+1,r,mid+1,b,v+d*(mid-a+1),d);    }}void clear(int p,int l,int r,int a,int b,int v){    if (l==a&&r==b){        pd[p]=v;        if (v) markcl(p);        return;    }    down(p,l,r);    int mid=(l+r)/2;    if (b<=mid) clear(p*2,l,mid,a,b,v);    else if (a>mid) clear(p*2+1,mid+1,r,a,b,v);    else{        clear(p*2,l,mid,a,mid,v);        clear(p*2+1,mid+1,r,mid+1,b,v);    }}int query(int p,int l,int r,int a){    if (l==r) return sx[p];    down(p,l,r);    int mid=(l+r)/2;    if (a<=mid) return query(p*2,l,mid,a);else return query(p*2+1,mid+1,r,a);}int main(){    freopen("bl.in","r",stdin);freopen("bl.out","w",stdout);    x0=read();y0=read();    ask[top=1].x=x0;ask[1].y0=y0;    n=read();    fo(i,1,n){        x1=read();y1=read();x2=read();y2=read();        if (x1>x2){            swap(x1,x2);            swap(y1,y2);        }        if (y1>y2) swap(y1,y2);        ask[++top].x=x1;        ask[top].ca=1;        ask[top].y0=y1;ask[top].y1=y2;        ask[++top].x=x2+1;        ask[top].ca=2;        ask[top].y0=y1;ask[top].y1=y2;    }    sort(ask+1,ask+top+1,cmp);    x=0;    change(1,1,maxm,mx+1,maxm,1,1);    change(1,1,maxm,1,mx-1,mx-1,-1);    fo(i,1,top){        change(1,1,maxm,1,maxm,ask[i].x-x,0);        x=ask[i].x;        if (ask[i].ca==0){            ans=query(1,1,maxm,ask[i].y0+mx);            break;        }        else if (ask[i].ca==1){            clear(1,1,maxm,ask[i].y0+mx,ask[i].y1+mx,1);        }        else if (ask[i].ca==2){            clear(1,1,maxm,ask[i].y0+mx,ask[i].y1+mx,0);            j=query(1,1,maxm,ask[i].y0-1+mx);            k=query(1,1,maxm,ask[i].y1+1+mx);            l=ask[i].y1-ask[i].y0+1;            t=(k+l+1-j)/2;            if (t<1) change(1,1,maxm,ask[i].y0+mx,ask[i].y1+mx,k+l,-1);            else if (t>l) change(1,1,maxm,ask[i].y0+mx,ask[i].y1+mx,j+1,1);            else{                change(1,1,maxm,ask[i].y0+mx,ask[i].y0+t-1+mx,j+1,1);                change(1,1,maxm,ask[i].y0+t+mx,ask[i].y1+mx,k+l-t,-1);            }        }    }    printf("%d\n",ans);}
0 0