题意描述

磁力块

在平面内分布着 \(N\) 个磁力块,同时你的手上也有一块。

你一开始站在给定的坐标上,当磁力块之间满足互相吸引的条件时就可以吸引。

当你拿到新的磁石时你就可以用它来吸引更多的石头,求你能吸引到的最多的磁石个数。

算法分析

既然一开始就确定了磁石,我们只需要依次 BFS 手上已有的磁石并吸引更多的磁石入队即可。

关键在于判定磁石能否被吸引,如果直接循环判断复杂度是 \(O(N^2)\) 的,所以需要数据结构来优化。

维护一个多维的结构貌似可以用平衡树,但是更好的方法是用代码复杂度小很多的分块来解决。

具体做法是将 \(N\) 个数按照质量大小排序之后分为 \(T\) 块,在每块内部在按照距离的远近排序。

同时维护每个块内最大质量为 \(H_i\)。

那么每次拿到一块磁石时就顺次遍历 \(T\) 个区间,每次如果磁力 \(\geq H_i\) 就直接遍历第 \(i\) 块来判断。

否则遍历整个区间并退出循环。(后面的质量一定大于磁力,不用做冗余判断)

遍历每个区间的均摊时间复杂度为 \(O(1)\),遍历 \(T\) 次为 \(O(T)\),加上 BFS 就为 \(O(NT)\)。

显然 \(T\) 取 \(\sqrt N\) 时最优,总时间复杂度为 \(O(N\sqrt N)\)。

代码实现

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<queue>
  7. #define N 2000010
  8. #define len 500
  9. using namespace std;
  10. typedef long long ll;
  11. ll n,tot,L[N],R[N],H[N];
  12. bool vis[N];
  13. struct node{
  14. ll d,r,m,p;
  15. }a[N];
  16. queue<ll>q;
  17. ll read(){
  18. ll x=0,f=1;char c=getchar();
  19. while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar();
  20. while(c>='0' && c<='9') x=x*10+c-48,c=getchar();
  21. return x*f;
  22. }
  23. bool cmp1(node a,node b){
  24. return a.m<b.m;
  25. }
  26. bool cmp2(node a,node b){
  27. return a.d<b.d;
  28. }
  29. int main(){
  30. ll x0,y0,x,y;
  31. x0=read();y0=read();a[0].p=read();a[0].r=read();
  32. n=read();
  33. a[0].r*=a[0].r;
  34. for(ll i=1;i<=n;i++){
  35. x=read();y=read();
  36. a[i].m=read();a[i].p=read();a[i].r=read();
  37. a[i].r*=a[i].r;
  38. a[i].d=(x0-x)*(x0-x)+(y0-y)*(y0-y);
  39. }
  40. sort(a+1,a+n+1,cmp1);
  41. for(ll i=1;i<=n;i+=len){
  42. L[++tot]=i;R[tot]=min(n,i+len-1);
  43. H[tot]=a[R[tot]].m;
  44. sort(a+L[tot],a+R[tot]+1,cmp2);
  45. }
  46. q.push(0);
  47. int ans=0;
  48. while(!q.empty()){
  49. ll now=q.front();
  50. ll r=a[now].r,p=a[now].p;
  51. q.pop();
  52. for(ll i=1;i<=tot;i++){
  53. if(H[i]>p){
  54. for(ll j=L[i];j<=R[i];j++)
  55. if(!vis[j] && a[j].d<=r && a[j].m<=p){
  56. q.push(j);vis[j]=true;ans++;
  57. }
  58. break;
  59. }
  60. while(L[i]<=R[i] && a[L[i]].d<=r){
  61. if(!vis[L[i]]){q.push(L[i]);ans++;}
  62. ++L[i];
  63. }
  64. }
  65. }
  66. printf("%lld\n",ans);
  67. return 0;
  68. }

完结撒❀。

【CHOJ】磁力块的更多相关文章

  1. CH#46A 磁力块

    题意 磁力块 CH Round #46 - 「Adera 8」杯NOI模拟赛 描述 在一片广袤无垠的原野上,散落着N块磁石.每个磁石的性质可以用一个五元组(x,y,m,p,r)描述,其中x,y表示其坐 ...

  2. 『磁力块 bfs 分块』

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

  3. CH#46 磁力块 分块

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

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

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

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

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

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

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

  7. CH Round #46A 磁力块

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

  8. [搜片神器]使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)

    谢谢园子朋友的支持,已经找到个VPS进行测试,国外的服务器:http://www.sosobta.com   大家可以给提点意见... 出售商业网站代码,万元起,非诚勿扰,谢谢. 联系h31h31 a ...

  9. 使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)

    使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源) 先直接上程序界面,了解整体工作流程是什么样子的,求服务器进行挂机测试,需要固定IP,空间大概需要10G左右(主要是BT种子占用空间 ...

随机推荐

  1. Hive中的数据类型以及案例实操

    @ 目录 基本数据类型 集合数据类型 案例实操 基本数据类型 对于Hive的String类型相当于数据库的varchar类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它 ...

  2. 编程源自生活:抽象 -> 生活中的洗头问题

    设计背景: 我:头上的油揩给了手,手接触洗手液.洗手液伤头皮,这样头皮就不会和洗手液接触了. 具体执行过程描述: 1.手揩油  ->  2.取液体  3.->洗手   我:这是什么设计模式 ...

  3. JavaFX ImageView

    例子1:显示4个狗头.正常显示左上角.右下角的狗头:右上角的狗头旋转180°,并设置了透明度:左下角的狗头旋转90°,也设置了透明度. 1 import javafx.application.Appl ...

  4. 基于Intel x86 Android的RAD游戏开发

    zip文件还包含编译的"MonkeyGame-debug".可以在模拟器中运行的二进制文件.在"game.build"文件夹中有一个HTML5 build.在C ...

  5. 如何检测ASP中的浏览器。NET与浏览器文件

    介绍 ASP.NET是一个用于使用Web表单.MVC.Web API和SignalR(这是官方定义)构建Web应用程序的高生产力框架.它是在.net框架上开发RESTful应用程序或使用HTML.CS ...

  6. cocos creator屏幕适配的一些知识点

    一. cocos creator 提供的几种适配策略 EXACT_FIT: 整个应用程序在指定区域可见,无需尝试保留原始纵横比.可能会出现失真,应用程序会被拉伸或压缩.也就是说设计分辨率的长和宽不会等 ...

  7. 54.Qt-将界面程序封装成动态库DLL

    1.生成dll 然后选择创建共享库: 创建好后,修改pro文件,改为下面两句(这样就可以创建界面了):  然后修改sharedlib.h: #ifndef SHAREDLIB_H #define SH ...

  8. 转一个veth的文章

    这篇写的很好,清晰明白,保存一下https://www.cnblogs.com/bakari/p/10613710.html

  9. es6深层次数组深拷贝

    let arr = [       {         label: '1',         children: [1, 2]       }     ] let a = [{...arr[0]}] ...

  10. 【图论】USACO07NOV Cow Relays G

    题目大意 洛谷链接 给定一张\(T\)条边的无向连通图,求从\(S\)到\(E\)经过\(N\)条边的最短路长度. 输入格式 第一行四个正整数\(N,T,S,E\),意义如题面所示. 接下来\(T\) ...