直接BFS貌似复杂度飞起来了,于是我们用k-d tree优化找点的过程即可。时间复杂度$O(n\sqrt{n})$。
#include<cstdio>
#include<algorithm>
const int N=10010,H=1000,R=1000000;
int n,m,i,root,cmp_d,h=1,t,q[N],f[N],mx,my,mz,ans;
inline void add(int x,int y){if(!f[x])f[q[++t]=x]=y;}
struct node{int d[2],l,r,Max[2],Min[2];}T[N];
inline bool cmp(node a,node b){
return (a.d[cmp_d]<b.d[cmp_d])||((a.d[cmp_d]==b.d[cmp_d])&&(a.d[!cmp_d]<b.d[!cmp_d]));
}
inline void umax(int&a,int b){if(a<b)a=b;}
inline void umin(int&a,int b){if(a>b)a=b;}
inline void up(int x){
if(T[x].l){
umax(T[x].Max[0],T[T[x].l].Max[0]);
umin(T[x].Min[0],T[T[x].l].Min[0]);
umax(T[x].Max[1],T[T[x].l].Max[1]);
umin(T[x].Min[1],T[T[x].l].Min[1]);
}
if(T[x].r){
umax(T[x].Max[0],T[T[x].r].Max[0]);
umin(T[x].Min[0],T[T[x].r].Min[0]);
umax(T[x].Max[1],T[T[x].r].Max[1]);
umin(T[x].Min[1],T[T[x].r].Min[1]);
}
}
int build(int l,int r,int D){
int mid=(l+r)>>1;
cmp_d=D,std::nth_element(T+l+1,T+mid+1,T+r+1,cmp);
T[mid].Max[0]=T[mid].Min[0]=T[mid].d[0];
T[mid].Max[1]=T[mid].Min[1]=T[mid].d[1];
if(l!=mid)T[mid].l=build(l,mid-1,!D);
if(r!=mid)T[mid].r=build(mid+1,r,!D);
return up(mid),mid;
}
inline int sqr(int x){return x*x;}
inline int max(int a,int b){return a>b?a:b;}
inline void ask(int x){
if(!x)return;
if(sqr(max(max(mx-T[x].Max[0],T[x].Min[0]-mx),0))+sqr(max(max(my-T[x].Max[1],T[x].Min[1]-my),0))>R)return;
if(sqr(T[x].d[0]-mx)+sqr(T[x].d[1]-my)<=R)add(x,mz);
ask(T[x].l);ask(T[x].r);
}
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
int main(){
for(read(m),read(n),i=1;i<=n;i++)read(T[i].d[0]),read(T[i].d[1]);
root=build(1,n,0);
for(i=1;i<=n;i++)if(T[i].d[1]<=H)add(i,1);
while(h<=t)mx=T[i=q[h++]].d[0],my=T[i].d[1],mz=f[i]+1,ask(root);
for(ans=n,i=1;i<=n;i++)if(f[i]&&T[i].d[1]+H>=m&&ans>f[i])ans=f[i];
return printf("%d",ans),0;
}