重点是bfs,分块只是优化bfs.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll N=2e5+6e4; const ll M=500;//块的大小 struct vv{ ll d,p,r,m;//距离 磁力 半径 质量 }a[N]; ll L[M],R[M],D[M];//每个块的左边和右边.每个块最右边的质量 bool vis[N]; queue<ll>q;//队列 bool cnp(vv x,vv y) { return x.d<y.d;//距离排序 } bool cmp(vv x,vv y) { return x.m<y.m;//质量排序 } int main() { ll x0,y0,pl,rl,n,tot=0; scanf("%lld%lld%lld%lld%lld",&x0,&y0,&pl,&rl,&n);//(x0,y0)是这个点 pl是你现在的磁力,rl是你的半径, a[0].p=pl;a[0].r=rl*rl; q.push(0); for(ll i=1;i<=n;i++) { ll x1,x2,x3,x4,x5; scanf("%lld%lld%lld%lld%lld",&x1,&x2,&x3,&x4,&x5); a[i].d=(x1-x0)*(x1-x0)+(x2-y0)*(x2-y0);//距离 a[i].m=x3;a[i].p=x4;a[i].r=x5*x5; } sort(a+1,a+1+n,cnp);//按距离排序. for(ll i=1;i<=n;i+=M) { L[++tot]=i; R[tot]=min(n,i+M-1); D[tot]=a[R[tot]].d; sort(a+L[tot],a+R[tot]+1,cmp);//把每块的质量进行排序. }//tot块. ll ans=0; while(q.size())//bfs { ll temp=q.front(); ll pos=a[temp].r; ll mat=a[temp].p; q.pop(); for(ll i=1;i<=tot;i++) { if(D[i]>pos)//假如说我的最右边的距离已经>我能所控制的距离,那么直接统计下这段符合 { for(ll j=L[i];j<=R[i];j++) { if(!vis[j]&&mat>=a[j].m&&a[j].d<=pos) { q.push(j); ans++; vis[j]=1; } } break; } while(mat>=a[L[i]].m&&L[i]<=R[i]) { if(!vis[L[i]]) { q.push(L[i]); ans++; } L[i]++; } } } cout<<ans<<endl; return 0; }