最简单的思路是离散化后 O(k2) O ( k 2 ) 搞
然而对于横着的朝向,极长的横着相连的格子的答案是相同的,竖着的同理
那么把极长的相连的格子也缩起来,用主席树优化建图,就可以 O(klogk) O ( k log k ) 最短路了
#include
#include
#include
#include
#include
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int N=50010;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
struct Line{
int l,r,g;
Line(){}
Line(int _l,int _r,int _g):l(_l),r(_r),g(_g){}
friend bool operator <(Line a,Line b){
return a.lint n,m,k,q,dis[N*200];
vector<int> h,s,hp[N<<2],sp[N<<2];
int x[N],y[N],sx,sy;
vector hl[N<<2],sl[N<<2];
vector ad[N<<2],de[N<<2];
int rt,ls[N*200],rs[N*200],ccnt;
int G[N*200],cnt;
struct edge{
int t,nx,w;
}E[N*400];
inline void addedge(int x,int y,int w){
//cerr<<'\t'<
E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt; E[cnt].w=w;
}
void add(int &g,int x,int l,int r,int y){
int k=g; g=++ccnt; ls[g]=ls[k]; rs[g]=rs[k];
if(l==r) return addedge(g,y,1);
int mid=l+r>>1;
if(x<=mid) add(ls[g],x,l,mid,y);
else add(rs[g],x,mid+1,r,y);
if(ls[g]) addedge(g,ls[g],0);
if(rs[g]) addedge(g,rs[g],0);
}
void link(int g,int l,int r,int L,int R,int y){
if(!g) return ;
if(l==L && R==r){
addedge(y,g,0); return ;
}
int mid=L+R>>1;
if(r<=mid) link(ls[g],l,r,L,mid,y);
else if(l>mid) link(rs[g],l,r,mid+1,R,y);
else link(ls[g],l,mid,L,mid,y),link(rs[g],mid+1,r,mid+1,R,y);
}
queue<int> Q;
int vis[N*200];
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
read(n); read(m); read(k); read(q);
for(int i=1;i<=k;i++){
read(x[i]); read(y[i]);
h.push_back(x[i]);
if(x[i]>1) h.push_back(x[i]-1);
if(x[i]1 );
s.push_back(y[i]);
if(y[i]>1) s.push_back(y[i]-1);
if(y[i]1);
}
read(sx); read(sy);
h.push_back(sx); s.push_back(sy);
if(sx>1) h.push_back(sx-1);
if(sx1);
if(sy>1) s.push_back(sy-1);
if(sy1);
h.push_back(n); s.push_back(m);
sort(h.begin(),h.end()); sort(s.begin(),s.end());
h.resize(unique(h.begin(),h.end())-h.begin());
s.resize(unique(s.begin(),s.end())-s.begin());
for(int i=1;i<=k;i++){
x[i]=lower_bound(h.begin(),h.end(),x[i])-h.begin();
y[i]=lower_bound(s.begin(),s.end(),y[i])-s.begin();
hp[x[i]].push_back(y[i]);
sp[y[i]].push_back(x[i]);
}
n=lower_bound(h.begin(),h.end(),n)-h.begin();
m=lower_bound(s.begin(),s.end(),m)-s.begin();
for(int i=0;iint lst=-1;
for(int j=0;jif(lst+11,hp[i][j]-1,++ccnt));
lst=hp[i][j];
}
if(lst+1<=m) hl[i].push_back(Line(lst+1,m,++ccnt));
}
for(int i=0;iint lst=-1;
for(int j=0;jif(lst+11,sp[i][j]-1,++ccnt));
lst=sp[i][j];
}
if(lst+1<=n) sl[i].push_back(Line(lst+1,n,++ccnt));
}
for(int i=0;ifor(int j=0;jfor(int i=0;ifor(int j=0;j0,s.size()-1,ad[i][j].se);
for(int j=0;j0,s.size()-1,hl[i][j].g);
ad[i].clear();
}
rt=0;
for(int i=0;ifor(int j=0;jfor(int i=0;ifor(int j=0;j0,h.size()-1,ad[i][j].se);
for(int j=0;j0,h.size()-1,sl[i][j].g);
}
sx=lower_bound(h.begin(),h.end(),sx)-h.begin();
sy=lower_bound(s.begin(),s.end(),sy)-s.begin();
int S1=hl[sx][upper_bound(hl[sx].begin(),hl[sx].end(),Line(sy,0,0))-hl[sx].begin()-1].g;
int S2=sl[sy][upper_bound(sl[sy].begin(),sl[sy].end(),Line(sx,0,0))-sl[sy].begin()-1].g;
for(int i=1;i<=ccnt;i++) dis[i]=1<<29;
dis[S1]=dis[S2]=0; Q.push(S1); Q.push(S2); vis[S1]=vis[S2]=1;
while(!Q.empty()){
int x=Q.front(); Q.pop(); vis[x]=0;
for(int i=G[x];i;i=E[i].nx)
if(dis[E[i].t]>dis[x]+E[i].w){
dis[E[i].t]=dis[x]+E[i].w;
if(!vis[E[i].t])
vis[E[i].t]=1,Q.push(E[i].t);
}
}
while(q--){
int x,y; read(x); read(y);
x=lower_bound(h.begin(),h.end(),x)-h.begin();
y=lower_bound(s.begin(),s.end(),y)-s.begin();
int T1=upper_bound(hl[x].begin(),hl[x].end(),Line(y,0,0))-hl[x].begin()-1;
int T2=upper_bound(sl[y].begin(),sl[y].end(),Line(x,0,0))-sl[y].begin()-1;
T1=hl[x][T1].g; T2=sl[y][T2].g;
int ans=min(dis[T1],dis[T2]);
if(ans==(1<<29)) ans=-1;
printf("%d\n",ans);
}
return 0;
}