Luogu P10590 磁力块
有一个很显然的 BFS,对于每一个吸到的新磁力块,遍历序列,把所有它能吸到的磁力块加入一个队列进行扩展。这样时间复杂度是 ,不能通过。
考虑影响是否能吸到的两个因素,一个是利用 计算出的距离,另一个是质量 。对于这种问题,经典的做法是排序维护第一个变量,数据结构维护第二个变量。
由于本题需要取出可以吸到的磁力块入队,故 数据结构在本题中不好用。我们考虑分块。把所有磁力块按照距离升序排序,每 个元素分成一块。块内按照 升序排序,并记录距离的最大值。
当我们扩展一个磁力块时,从小到大遍历序列中的每一块。
对于一个最大距离小于等于吸引半径的块,所有磁力块均处于吸引半径之内。可以对于每一块记录一个 ,表示块中已经前 个磁力块已经被吸引。我们只需要利用 ,遍历到第 个元素,使这个元素的 大于当前吸力即可。由于 升序排序,所以这一块中所有可以被吸走的磁力块要么在之前被吸走,要么在这一次被吸走,满足条件。之后,令 。
对于第一个最大距离大于吸引半径的块,根据遍历顺序以及距离升序排序,之后的块中所有元素距离必然大于吸引半径,可以处理完这一块之后退出循环。这一块之中有的磁力块可以被吸走,有的磁力块不可以被吸走。我们暴力求出每一个能够吸走的磁力块,标记已经被吸走,之后排序重构。均衡复杂度之后为 ,可以通过。
事实上,可以继续优化。在处理第一个最大距离大于吸引半径的块时,我们不进行排序重构。改为在处理最大距离小于等于吸引半径的块时,如果遇到一个被吸走的磁力块,直接跳过到下一个。由于 升序排序,依旧满足要求。时间复杂度 。
#include <bits/stdc++.h>
using namespace std;
struct val
{
long long m,p,r;
double d;
}a[300000];
long long xq,yq,x,y,p,r,n,k,qp[300000],qr[300000],h=1,t=0,id[300000],la[300000],lc[300000],rc[300000],ans=-1;
double mx[300000];
bool cmp1(struct val a,struct val b)
{
return a.d<b.d;
}
bool cmp2(struct val a,struct val b)
{
return a.m<b.m;
}
double dist(long long x1,long long y1,long long x2,long long y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void expand(long long p,long long r)
{
for(int i=1;i<=(n+k-1)/k;i++)
if(mx[i]<=r)
while(a[la[i]].m<=p&&la[i]<=rc[i])
{
if(a[la[i]].m!=-1e10)qp[++t]=a[la[i]].p,qr[t]=a[la[i]].r,a[la[i]].m=-1e10;
la[i]++;
}
else
{
la[i]=lc[i];
for(int j=lc[i];j<=rc[i];j++)
if(a[j].m!=-1e10&&a[j].m<=p&&a[j].d<=r)qp[++t]=a[j].p,qr[t]=a[j].r,a[j].m=-1e10;
break;
}
}
int main()
{
scanf("%lld%lld%lld%lld%lld",&xq,&yq,&p,&r,&n);
qp[++t]=p,qr[t]=r,k=sqrt(n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld%lld%lld",&x,&y,&a[i].m,&a[i].p,&a[i].r);
a[i].d=dist(xq,yq,x,y);
}
sort(a+1,a+n+1,cmp1);
for(int i=1;i<=(n+k-1)/k;i++)lc[i]=1e10;
for(long long i=1;i<=n;i++)id[i]=(i-1)/k+1,lc[id[i]]=min(lc[id[i]],i),rc[id[i]]=max(rc[id[i]],i),mx[id[i]]=max(mx[id[i]],a[i].d);
for(int i=1;i<=(n+k-1)/k;i++)la[i]=lc[i],sort(a+lc[i],a+rc[i]+1,cmp2);
while(h<=t)ans++,expand(qp[h],qr[h]),h++;
printf("%lld\n",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探