题意

磁力块 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. unity3D开发的程序发布到Android平台上进行运行测试的详细步骤

    第一步    下载安装JDK 和SDK 1.需要配置java环境.点击链接进入ava的配置的方法:http://www.cnblogs.com/Study088/p/7496158.html 2.下载 ...

  2. day4-python基础-运算符

    本章节主要说明Python的运算符.举个简单的例子 4 +5 = 9 . 例子中,4 和 5 被称为操作数,"+" 称为运算符. Python语言支持以下类型的运算符: 算术运算符 ...

  3. JavaScript 操作DOM对象

    1)JavaScript  操作DOM對象 1.DOM:是Document  Object  Model 的缩写,及文档对象模型 2.DOM通常分为三类:DOM Core(核心).HTML-DOM 和 ...

  4. 查找xml中的接口名及涉及表名并输出

    #! /usr/bin/env python3 # -*- coding:utf-8 -*- import xml.dom.minidom  #该模块被用来处理xml文件 import re #正则表 ...

  5. Linux学习 :移植U-boot_2012.04.01到JZ2440开发板

    一.下载U-boot源码:ftp://ftp.denx.de/pub/u-boot/ 二.uboot的启动过程: 部分硬件初始化——>加载完整uboot到RAM——>跳转到第二阶段入口开始 ...

  6. elk之elasticsearch安装

    环境: centos7 jdk8 参考: https://www.elastic.co/guide/en/elasticsearch/reference/current/rpm.htmlhttp:// ...

  7. 20165326 java第六周学习笔记

    第六周学习总结 ch8 String类对于有效处理字符序列信息非常重要. String对象的字符序列不能被修改删除,无法发生变化. StringBuffer类的对象实体的内存空间可以自动改变大小,便于 ...

  8. Python 基础数据类型相互转换

    字符串,数字,列表 ,元祖,字典 化相互转化 1 Int 与 str 之间如何转化,转换的结果是什么?有没有条件?     #str(int型)可以转化为str 该过程没有条件     #字符串转化为 ...

  9. JAVA测试编程

    本周我们上JAVA课的时候进行了一次测试,本次测试以模拟中国工商银行自助机ATM的功能为大致要求,要求我们进行编写调试,以求达到试题要求. 测试要求我们能模拟ATM的功能设计,当用户插卡后显示,输入密 ...

  10. 性能测试-8.LR常用函数

    1.变量转参数 lr_save_string("参数内容","param"):将字符串“aaa”或者一个字符串变量,转变成LR的参数{param} 2.参数转变 ...