『磁力块 bfs 分块』
<更新提示>
<第一次更新>
<正文>
磁力块
Description
在一片广袤无垠的原野上,散落着N 块磁石。每个磁石的性质可以用一个五元组 (x,y,m,p,r)描述,其中x,y 表示其坐标,m 是磁石的质量,p 是磁力,r 是吸引半径。若磁石 A 与磁石B 的距离不大于磁石A 的吸引半径,并且磁石B 的质量不大于磁石A 的磁力,那 么A 可以吸引B。
小取酒带着一块自己的磁石L 来到了这篇原野的(x0,y0)处,我们可以视为磁石L 的坐 标为(x0,y0)。小取酒手持磁石L 并保持原地不动,所有可以被L 吸引的磁石将会被吸引过 来。在每个时刻,他可以选择更换任意一块自己已经获得的磁石(当然也可以是自己最初携 带的L 磁石)在(x0,y0)处吸引更多的磁石。小取酒想知道,他最多能获得多少块磁石呢?
Input Format
第一行五个整数x0,y0,pL,rL,N,表示小取酒所在的位置,磁石L 磁力、吸引半径和原野 上散落磁石的个数。
接下来N 行每行五个整数x,y,m,p,r,描述一块磁石的性质。
Output Format
输出一个整数,表示最多可以获得的散落磁石个数(不包含最初携带的磁石L)。
Sample Input
0 0 5 10 5
5 4 7 11 5
-7 1 4 7 8
0 2 13 5 6
2 -3 9 3 4
13 5 1 9 9
Sample Output
3
解析
显然我们可以建立一个\(bfs\)框架,队列中存储着每一次已经拿到的磁石,然后每次尝试用队头的磁石去吸引其他磁石,能够吸引到其他磁石就把磁石加入到队尾,直到队列为空。
那么我们需要解决的问题就是快速地判断哪些磁石能够被吸引,而判断是否能够被吸引的有两个关键信息:"质量"和"距离",我们考虑如下的分块算法:
将\(n\)块石头按照质量排序,分为\(\sqrt n\)段,每一段中再按距离排序。
那么对于每一次队首的磁石,一定存在一段满足:这段以前所有磁石质量都小于当前队首磁石的磁力,这段以后所有磁石质量都大于当前队首磁石的磁力。
对于前一部分,由于每一段内部已经按照距离重新排过序,那么可以被吸引的磁石就一定在这些段的左端,对每一段将吸引的磁石加入,并将该段的开头移动到没有被吸引的第一个位置即可。
对于这一段,直接暴力扫描,将能吸引的磁石处理掉即可。
对于前一种处理方式来说,均摊复杂度是\(O(1)\)的,总复杂度为\(O(\sqrt n)\),对于朴素扫描的的那一段来说,时间复杂度也是\(O(\sqrt n)\),所以总的时间复杂度就是\(O(n\sqrt n)\)。
\(Code:\)
#include <bits/stdc++.h>
using namespace std;
const int N = 250020 , SIZE = 5200;
struct magnet
{
long long m,p,r,dis;
};
magnet a[N],st;
long long n,x_,y_,l[SIZE],r[SIZE],belo[N],T,size,ans,flag[N],Maxm[SIZE];
inline long long calc(long long x1,long long y1,long long x2,long long y2)
{
return (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2);
}
inline void input(void)
{
scanf("%lld%lld%lld%lld%lld",&x_,&y_,&st.p,&st.r,&n);
st.m = 0 , st.dis = 0 , st.r *= st.r;
for (int i=1;i<=n;i++)
{
long long x,y,m,p,r;
scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&p,&r);
a[i] = (magnet){m,p,r*r,calc(x,y,x_,y_)};
}
}
inline void setblocks(void)
{
T = sqrt(n) , size = n/T;
for (int i=1;i<=T;i++)
{
if ( i * size > n ) break;
l[i] = (i-1) * size + 1;
r[i] = i * size;
}
if ( r[T] < n ) T++ , l[T] = r[T-1] + 1 , r[T] = n;
for (int i=1;i<=T;i++)
for (int j=l[i];j<=r[i];j++)
belo[j] = i;
}
inline bool compare_m(magnet p1,magnet p2)
{
return p1.m < p2.m;
}
inline bool compare_d(magnet p1,magnet p2)
{
return p1.dis < p2.dis;
}
inline void init(void)
{
sort( a+1 , a+n+1 , compare_m );
for (int i=1;i<=T;i++)
Maxm[i] = a[r[i]].m , sort( a+l[i] , a+r[i]+1 , compare_d );
}
inline void bfs(void)
{
queue < magnet > q;
q.push(st);
while ( !q.empty() )
{
magnet t = q.front();
q.pop(); ans ++;
for (int i=1;i<=T;i++)
{
if ( Maxm[i] <= t.p )
{
for (int j=l[i];j<=r[i];j++)
{
if ( a[j].dis <= t.r )
{
if ( !flag[j] )
flag[j] = true , q.push(a[j]);
}
else {l[i] = j; break;}
if ( j == r[i] ) l[i] = r[i] + 1;
}
}
else
{
for (int j=l[i];j<=r[i];j++)
if ( !flag[j] && a[j].dis <= t.r && a[j].m <= t.p )
flag[j] = true , q.push(a[j]);
break;
}
}
}
}
int main(void)
{
input();
setblocks();
init();
bfs();
printf("%lld\n",ans-1);
return 0;
}
<后记>
『磁力块 bfs 分块』的更多相关文章
- CH#46A 磁力块
题意 磁力块 CH Round #46 - 「Adera 8」杯NOI模拟赛 描述 在一片广袤无垠的原野上,散落着N块磁石.每个磁石的性质可以用一个五元组(x,y,m,p,r)描述,其中x,y表示其坐 ...
- 【CHOJ】磁力块
题意描述 磁力块 在平面内分布着 \(N\) 个磁力块,同时你的手上也有一块. 你一开始站在给定的坐标上,当磁力块之间满足互相吸引的条件时就可以吸引. 当你拿到新的磁石时你就可以用它来吸引更多的石头, ...
- 重新学习MySQL数据库2:『浅入浅出』MySQL 和 InnoDB
重新学习Mysql数据库2:『浅入浅出』MySQL 和 InnoDB 作为一名开发人员,在日常的工作中会难以避免地接触到数据库,无论是基于文件的 sqlite 还是工程上使用非常广泛的 MySQL.P ...
- 『浅入深出』MySQL 中事务的实现
在关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的:在这篇文章中,我们将对事务的实现进行分析,尝 ...
- MuPlayer『百度音乐播放内核』
MuPlayer『百度音乐播放内核』 —— 跨平台.轻量级的音频播放解决方案. 多端(PC & WebApp)通用,统一的API调用方式 HTML5 Audio与Flash内核的平滑切换(支持 ...
- 【阿里云产品公测】以开发者角度看ACE服务『ACE应用构建指南』
作者:阿里云用户mr_wid ,z)NKt# @I6A9do 如果感觉该评测对您有所帮助, 欢迎投票给本文: UO<claV RsfTUb)< 投票标题: 28.[阿里云 ...
- 『HTML5梦幻之旅』-缤纷多姿的烟花效果
天花无数月中开,五采祥云绕绛台.堕地忽惊星彩散,飞空旋作雨声来.怒撞玉斗翻晴雪,勇踏金轮起疾雷.更漏已深人渐散,闹竿挑得彩灯回. ——明·瞿佑·<烟火戏> 记得每年过春节的那段时间,除了欣 ...
- 『NiFi 学习之路』简介
『NiFi 学习之路』简介 『NiFi 学习之路』入门 -- 下载.安装与简单使用 『NiFi 学习之路』资源 -- 资料汇总 『NiFi 学习之路』把握 -- 架构及主要组件 『NiFi 学习之路』 ...
- 『NiFi 学习之路』自定义 —— 组件的自定义及使用
一.概述 许多业务仅仅使用官方提供的组件不能够满足性能上的需求,往往要通过高度可定制的组件来完成特定的业务需求. 而 NiFi 提供了自定义组件的这种方式. 二.自定义 Processor 占坑待续 ...
随机推荐
- 浅谈华为验厂对MES系统的要求
众所周知,华为对供应商在管理.防错.品控.追溯等方面的要求都非常严格.在华为验厂时,对供应商的信息系统,尤其是MES系统的评估也是有非常具体的要求.那么我们今天就来谈谈华为验厂时,对MES系统有哪些具 ...
- linux安装包制作
1. 常见安装包 打包或压缩文件tar,zip,gz等,一般解压后即可 管理工具的deb,rpm等.这类安装文件可以通过第三方的命令安装 (apt和yum) .bin类,其实就是把sh和zip打包为b ...
- docker的centos7安装与启动相关命令
Docker 的概念 Docker 是一个开源工具,它可以让创建和管理 Linux 容器变得简单.容器就像是轻量级的虚拟机,并且可以以毫秒级的速度来启动或停止.Docker 帮助系统管理员和程序员在容 ...
- 《linux就该这么学》课堂笔记19 iSCSI、MariaDB、无人值守安装
1.iSCSI技术介绍 硬盘是计算机硬件设备中重要的组成部分之一,硬盘存储设备读写速度的快慢也会对服务器的整体性能造成影响. 为了进一步提升硬盘存储设备的读写速度和性能,人们一直在努力改进物理硬盘设备 ...
- Linux 批量查找并替换文件夹下所有文件的内容
1.批量查找某个目下文件的包含的内容 cd etc grep -rn "查找的内容" ./ 2.批量替换某个目下所有包含的文件的内容 cd etc sed -i "s/查 ...
- django-URL路由系统
配置 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表.你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个U ...
- pycharm与github的使用
1.clone代码: 输入github的存储库地址,输入本地存储目录,点击clone即可: 2.上传代码: 输入存储库名字,点击share即可:github上就会有你分享的代码啦
- debug模式不报错,release模式报错
经常会 char * pMem = new char[icount]; 其中icount为变量,然后对该内存段猛的操作.release编译出来,出现莫名奇妙的错误.但是debug没问题. 后面查了别人 ...
- 某模拟赛C题 树上路径统计 (点分治)
题意 给定一棵有n个节点的无根树,树上的每个点有一个非负整数点权.定义一条路径的价值为路径上的点权和-路径上的点权最大值. 给定参数P,我!=们想知道,有多少不同的树上简单路径,满足它的价值恰好是P的 ...
- RabbitMQ消息确认机制
文章目录 1. 事务机制2. Confirm模式2.1 生产者2.1.1 普通Confirm模式2.1.2 批量Confirm模式2.1.3 异步Confirm模式2.2 消费者3. 其他 消费者如何 ...