题目描述
腐女要过生日了,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);
}