题意

磁力块 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. python 进程创建和共享内容的方法

    1.使用Pool来创建进程 from multiprocessing import Pool def f(n): return n*n if __name__=="__main__" ...

  2. Saiku的基本使用介绍(三)

    Saiku的基本使用介绍(这里都是使用Admin用户登录系统) 1.启动安装好的Saiku  ( ./start-saiku.sh ) ,浏览器使用访问系统 http://localhost:8080 ...

  3. 每天CSS学习之box-shadow

    box-shadow是CSS3的属性,目的是给盒子添加一个或多个阴影.怎么感觉有点像光明使者使用该法术照亮敌人的阴暗面? box-shadow一共有六个属性,请看: box-shadow: h-sha ...

  4. PC/FORTH 编辑程序

    body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...

  5. win10环境下安装Ubantu双系统(超详解)

    win10环境下安装Ubantu双系统 1.准备工作: 先去ubantu官网(https://www.ubuntu.com/download)去下载ubantu镜像.根据自己的实际情况选择32位的或者 ...

  6. sass的加减乘除

    运算 时单位要一样 否则报错 除法时 要加() width: (100px / 2); 符号在已有的数学表达式中时,也会被认作除法符号,就不要加() .box { width: 100px / 2 + ...

  7. Android : 获取声卡信息的测试代码

    完整的编译包(android平台): 链接:http://pan.baidu.com/s/1qXMTT7I 密码:2bow /* * ALSA parameter test program * * C ...

  8. 特殊权限set_gid

    set gid: 权限说明: set gid权限可以作用在文件上(二进制可执行文件),也可以作用在目录上.当作用在文件上时,其功能和set,uid一样,它会使文件在执行阶段具有文件所属组的权限.目录被 ...

  9. 强化学习9-Deep Q Learning

    之前讲到Sarsa和Q Learning都不太适合解决大规模问题,为什么呢? 因为传统的强化学习都有一张Q表,这张Q表记录了每个状态下,每个动作的q值,但是现实问题往往极其复杂,其状态非常多,甚至是连 ...

  10. 软件开发模式,DevOps

    参考文献:http://www.cnblogs.com/jetzhang/p/6068773.html 历史回顾 为了能够更好的理解什么是DevOps,我们很有必要对当时还只有程序员(此前还没有派生出 ...