磁力块(分块)

news/2024/11/22 19:25:22/

题目链接

在这里插入图片描述

输入格式

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

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

输出格式

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

数据范围

1 ≤ N ≤ 250000 , 1≤N≤250000, 1N250000,
− 1 0 9 ≤ x , y ≤ 1 0 9 , −10^9≤x,y≤10^9, 109x,y109,
1 ≤ m , p , r ≤ 1 0 9 1≤m,p,r≤10^9 1m,p,r109

输入样例:

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

思路

如果磁石的属性只有重量 m m m 这一维,那么根据 m m m 从小到大排序,将已有的磁石加入队列,从小到大扫描排序后的磁石,若能吸引第 i i i 个磁石,则将其加入队列,并且记录前 i i i 个磁石都已被吸引。不断用队首的磁石进行这一操作,就可以计算出最终能吸引的磁石的数量。

但是,这题多了距离 r r r 这个因素,如果依旧按照上面的方法,无法保证吸引第 i i i 块磁石后,前 i i i 块磁石都可以被吸引。这样整个序列始终是杂乱的,无法很好地维护。

这种方法其实是将整个序列看做是一个“块”,这个“块”太大了,才无法有效管理。

可以对序列先根据重量 m m m 升序排序,再分块,每个块中再按距离 r r r 升序排序。这样,每个块之间可以保证 m m m 是递增的,块内保证 r r r 是递增的。有了一定的规律,才有更好的维护方法。

当用某块磁石吸引时,可以找到一个 k k k ,使得前 k − 1 k-1 k1 个分块的磁石重量都可以被吸引, k + 1 k+1 k+1 之后的分块中,磁石的重量都无法被吸引。
对于前 k − 1 k-1 k1 块,每个块内从小到大扫描,若距离也可以被吸引,那么就把这个磁石 j j j 加入队列,同时把该分块的左端点设为j+1。这些已扫描过的磁石之后不会再重复计算。
对于第 k k k 个分块,暴力维护,从左到右扫描每个磁石,判断是否加入队列,若加入,则 v i s vis vis 数组记录已访问。

用这种分块做法,只需要暴力维护大小为 n \sqrt n n 的区间。

#include<bits/stdc++.h>
using namespace std;
const int N=2.5e5+10;
int x,y,p,r,n,t,L[N],R[N],maxM[N],vis[N],cnt;
struct P{int x,y,m,p,r;long long R;}a[N];
queue<tuple<int,int,int,int,int>> que;bool cmp2(P a,P b){ return a.R<b.R; }bool cmp1(P a,P b){ return a.m<b.m; }int main(){scanf("%d%d%d%d%d",&x,&y,&p,&r,&n);for(int i=1;i<=n;i++){scanf("%d%d%d%d%d",&a[i].x,&a[i].y,&a[i].m,&a[i].p,&a[i].r);a[i].R=1LL*(a[i].x-x)*(a[i].x-x)+1LL*(a[i].y-y)*(a[i].y-y);}t=sqrt(n);for(int i=1;i<=t;i++){L[i]=(i-1)*t+1;R[i]=i*t;}if(R[t]<n)  t++,L[t]=R[t-1]+1,R[t]=n;sort(a+1,a+n+1,cmp1);for(int i=1;i<=t;i++){maxM[i]=a[R[i]].m;sort(a+L[i],a+R[i]+1,cmp2);}que.emplace(x,y,0,p,r);while(que.size()){auto [x,y,m,p,r]=que.front();   que.pop();for(int i=1;i<=t;i++){if(maxM[i]<=p){for(int j=L[i];j<=R[i];j++){if(vis[j]==1){  L[i]=j;continue;    }if(a[j].R<=1LL*r*r)que.emplace(a[j].x,a[j].y,a[j].m,a[j].p,a[j].r),vis[j]=1,L[i]=j+1,cnt++;else    break;}}else{for(int j=L[i];j<=R[i];j++)if(a[j].m<=p&&a[j].R<=1LL*r*r&&vis[j]==0)que.emplace(a[j].x,a[j].y,a[j].m,a[j].p,a[j].r),vis[j]=1,cnt++;break;}}}printf("%d\n",cnt);
}

http://www.ppmy.cn/news/789078.html

相关文章

海洋磁力数据处理步骤

​ &#xff08;此照片乃航次获奖照片&#xff09; 前面几个章节介绍了地磁基本知识&#xff0c;由于项目紧急&#xff0c;只能边学习理论&#xff0c; 边处理。经过2个月的努力&#xff0c;基本上掌握了海洋重磁处理的基本方法。 目前&#xff0c;专项的重磁处理都是各单位自己…

磁力链接做成rar文件后怎么打开

要打开 RAR 文件&#xff0c;首先需要安装一个 RAR 解压缩软件。 Windows 系统自带的资源管理器不能直接解压 RAR 文件&#xff0c;所以需要使用第三方软件。 常用的 RAR 解压缩软件有&#xff1a; WinRAR(收费)7-Zip(免费) 安装完解压缩软件之后&#xff0c;打开 RAR 文件可以…

磁力块

题目链接 在一片广袤无垠的原野上&#xff0c;散落着 N N N块磁石。 每个磁石的性质可以用一个五元组 ( x , y , m , p , r ) (x,y,m,p,r) (x,y,m,p,r)描述&#xff0c;其中 x , y x,y x,y表示其坐标&#xff0c; m m m是磁石的质量&#xff0c; p p p是磁力&#xff0c; r r …

基于matlab使用激光雷达检测地平面和障碍物(附源码)

一、前言 此示例演示如何通过分割地平面并查找附近的障碍物来处理来自安装在车辆上的传感器的 3-D 激光雷达数据。这可以促进车辆导航的可驾驶路径规划。该示例还演示如何可视化流式激光雷达数据。 二、创建 Velodyne 文件读取器 本例中使用的激光雷达数据是使用安装在车辆上…

find和grep各个参数

find 功能&#xff1a;在目录结构中搜索文件&#xff0c;并执行指定的操作。此命令提供了相当多的查找条件&#xff0c;功能很强大。 语法: find 查找位置 匹配文件名 说明&#xff1a;find命令从指定的起始目录开始&#xff0c;递归地搜索其各个子目录&#xff0c;查找满足…

开源免费录屏软件整理

百度了好多软件&#xff0c;大多限制时间或者质量不好或者有水印&#xff0c;以下三款无水印、无广告、清晰度高&#xff0c;记录以下。 1.ScreenToGif gif短动画录制 它的Github开源项目地址在这里&#xff0c;下载地址在这里。 2.Captura 这个录制视频有声音&#xff0c…

电脑录屏用什么软件?推荐这3款软件,用过都说好

如今网络中&#xff0c;有很多的软件都能够实现电脑录屏。但想要找一个方便好用的电脑录屏软件却十分困难。电脑录屏用什么软件&#xff1f;今天小编将为小伙伴分享3款超级方便好用的电脑录屏软件&#xff0c;用过的小伙伴都说好&#xff01;一起来看看吧。 电脑录屏软件1&…

6种电脑录屏工具,免费在线,桌面端Windows和Mac均适用

如果你想做一个教程类博主&#xff0c;不管是游戏类的&#xff0c;科技类的&#xff0c;还是语言类的&#xff0c;你首先需要一个不错的电脑录屏工具。自自媒体大流行开始以来&#xff0c;对电脑屏幕录制的需求有不断增长。来自不同领域的专业人士&#xff0c;例如教育领域的专…