题意

磁力块 CH Round #46 - 「Adera 8」杯NOI模拟赛

描述

在一片广袤无垠的原野上,散落着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)处吸引更多的磁石。小取酒想知道,他最多能获得多少块磁石呢?

输入格式

第一行五个整数x0,y0,pL,rL,N,表示小取酒所在的位置,磁石L磁力、吸引半径和原野上散落磁石的个数。

接下来N行每行五个整数x,y,m,p,r,描述一块磁石的性质。

输出格式

输出一个整数,表示最多可以获得的散落磁石个数(不包含最初携带的磁石L)。

样例输入

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

样例输出

3

数据范围与约定

  • 对于30%的数据,1<=N<=1000。
  • 对于100%的数据,1<=N<=250000,-10^9<=x,y<=10^9,1<=m,p,r<=10^9。
        </article>

分析

容易想到BFS框架,需要判断哪些磁石能被吸引。能被吸引的条件是 质量≤磁力 且 距离≤吸引半径。考虑分块。

磁石按照质量排序后分成sqrt(N)块,每块内部按照距离排序。然后用每块获得的磁石去尝试吸引其它磁石。那么一定存在一个k,使得[1,k-1]块中的磁石质量都不大于该磁石的吸引力。相当于在前k-1块的开头取出若干磁石(均摊O(1)),在第k块中暴力扫描哪些磁石可以被取出(O(sqrt(N))),总复杂度\(O(N \sqrt{N})\)。这是最好写的做法。

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std; co int N=2.5e5+1;
struct P{
int x,y,m,p,r;
}p[N],q[N];
bool b[N];
int n,L[N],R[N],M[N];
bool cmp(co P&a,co P&b){
return a.m<b.m;
}
bool cmp0(co P&a,co P&b){
return (ll)(a.x-q[0].x)*(a.x-q[0].x)+(ll)(a.y-q[0].y)*(a.y-q[0].y)<(ll)(b.x-q[0].x)*(b.x-q[0].x)+(ll)(b.y-q[0].y)*(b.y-q[0].y);
}
bool pd(co P&a,co P&b){
return (ll)(q[0].x-b.x)*(q[0].x-b.x)+(ll)(q[0].y-b.y)*(q[0].y-b.y)<=(ll)a.r*a.r;
}
int main(){
// freopen(".in","r",stdin),freopen(".out","w",stdout);
read(q[0].x),read(q[0].y),read(q[0].p),read(q[0].r),read(n);
for(int i=1;i<=n;++i) read(p[i].x),read(p[i].y),read(p[i].m),read(p[i].p),read(p[i].r);
sort(p+1,p+n+1,cmp);
int t=sqrt(n);
for(int i=1;i<=t;++i){
L[i]=(i-1)*t+1,R[i]=i*t,M[i]=p[R[i]].m;
sort(p+L[i],p+R[i]+1,cmp0);
}
if(R[t]<n){
L[t+1]=R[t]+1,R[++t]=n,M[t]=p[R[t]].m;
sort(p+L[t],p+R[t]+1,cmp0);
}
int l=0,r=1; // [l,r)
while(l<r){
int k=0;
for(int i=1;i<=t;++i){
if(M[i]<=q[l].p) k=i;
else break;
}
for(int i=1;i<=k;++i)
while(L[i]<=R[i]&&pd(q[l],p[L[i]])){
if(!b[L[i]]) b[L[i]]=1,q[r++]=p[L[i]];
++L[i];
}
if(k++!=t)for(int i=L[k];i<=R[k];++i)
if(!b[i]&&p[i].m<=q[l].p&&pd(q[l],p[i]))
b[i]=1,q[r++]=p[i];
++l;
}
printf("%d\n",r-1);
return 0;
}

CH#46A 磁力块的更多相关文章

  1. CH #46A - 磁力块 - [分块]

    题目链接:传送门 描述在一片广袤无垠的原野上,散落着N块磁石.每个磁石的性质可以用一个五元组(x,y,m,p,r)描述,其中x,y表示其坐标,m是磁石的质量,p是磁力,r是吸引半径.若磁石A与磁石B的 ...

  2. CH Round #46A 磁力块

    还是一道好题的 对于一个磁石是否被吸引,有两个关键字:距离和质量.(二维偏序??) 好像是很厉害的分块姿势,先按第一关键字排序,在块中按第二关键字排 进行bfs,对于当前磁石,有1~k-1个块是第一关 ...

  3. CH#46 磁力块 分块

    正解:分块+bfs 解题报告: 先放个传送门,然后瞎扯淡下QAQ 突然感觉不停课大概是正确的选择QAQ 大概实在是没有天赋?明明都知道正解是分块甚至还听了下解法感觉理解了,再看一次依然没想到解法,,, ...

  4. 『磁力块 bfs 分块』

    磁力块 Description 在一片广袤无垠的原野上,散落着N 块磁石.每个磁石的性质可以用一个五元组 (x,y,m,p,r)描述,其中x,y 表示其坐标,m 是磁石的质量,p 是磁力,r 是吸引半 ...

  5. 【CHOJ】磁力块

    题意描述 磁力块 在平面内分布着 \(N\) 个磁力块,同时你的手上也有一块. 你一开始站在给定的坐标上,当磁力块之间满足互相吸引的条件时就可以吸引. 当你拿到新的磁石时你就可以用它来吸引更多的石头, ...

  6. Contest Hunter #46 T1 磁力块 [分块]

    描述 在一片广袤无垠的原野上,散落着N块磁石.每个磁石的性质可以用一个五元组(x,y,m,p,r)描述,其中x,y表示其坐标,m是磁石的质量,p是磁力,r是吸引半径.若磁石A与磁石B的距离不大于磁石A ...

  7. Contest Hunter #46 T1 磁力块 [花式暴力]

    将所有石头按距离远近排序,将所有取到的时候扔进堆里维护最大磁力强度. 贪心,每次用强度最强的磁石尝试吸引地上的石头,扫完区间以后,这块石头就再也不会用到了. 在此基础上可以做些小优化,比如说优化未取石 ...

  8. JAVA基础知识之IO——Java IO体系及常用类

    Java IO体系 个人觉得可以用"字节流操作类和字符流操作类组成了Java IO体系"来高度概括Java IO体系. 借用几张网络图片来说明(图片来自 http://blog.c ...

  9. CFileDialog 多文件选择

    CString pathName = _T(""); CString fileName = _T(""); CString strMulfilepath = _ ...

随机推荐

  1. linux:centOs7换源阿里云

    备份: mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 下载: wget -O /etc/y ...

  2. pytorch加载和保存模型

    在模型完成训练后,我们需要将训练好的模型保存为一个文件供测试使用,或者因为一些原因我们需要继续之前的状态训练之前保存的模型,那么如何在PyTorch中保存和恢复模型呢? 方法一(推荐): 第一种方法也 ...

  3. ubuntu14.04 解析不了域名—ubuntu的DNS配置

    问题描述: 电脑系统为ubuntu14.04,连上无线后,火狐浏览器打开www.baidu.com,提示找不到服务器,以及终端ping www.baidu.com,提示unkown host,但是浏览 ...

  4. 2.18 C++类与static关键字

    参考:http://www.weixueyuan.net/view/6349.html 总结: 类中的成员变量或成员函数一旦与static关键字相结合,则该成员变量或成员函数就是属于类的,而不是再是属 ...

  5. java构造函数使用方法总结 (继承与构造函数)

    使用构造器时需要记住: 1.构造器必须与类同名(如果一个源文件中有多个类,那么构造器必须与公共类同名) 2.每个类可以有一个以上的构造器 3.构造器可以有0个.1个或1个以上的参数 4.构造器没有返回 ...

  6. elk之logstash

    环境: centos7 jdk8 1.创建Logstash源 rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch touch ...

  7. 继承映射中的java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: person is not mapped [FROM person]

    继承映射中查询对象的过程中报错: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxExcep ...

  8. mysql cast

    之前讲到了orcale的字符串与日期等类型的转换,现在我们来看看Mysql是怎么转换的.比起orcale,MySQL相比之下就简单得多了,只需要一个Cast()函数就能搞定.其语法为:Cast(字段名 ...

  9. django面试大全

    1.Django请求的生命周期 a. wsgi, 创建socket服务端,用于接收用户请求并对请求进行初次封装. b. 中间件,对所有请求到来之前,响应之前定制一些操作. c. 路由匹配,在url和视 ...

  10. Fedora 10编程开发工具

    1请问Fedora 10编程开发工具有什么 编辑器就用vim,编译用gcc,当然个人爱好随意 IDE的话推荐eclipse,如果做C/C++的,用codeblocks也是个不错的选择 输入gcc -v ...