当前位置: 首页 > news >正文

【2024最新】C++扫描线算法介绍+实战例题

扫描线介绍:OI-Wiki

【简单】一维扫描线(差分优化)

网上一维扫描线很少有人讲,可能认为它太简单了吧,也可能认为这应该算在差分里(事实上讲差分的文章里也几乎没有扫描线的影子)。但我认为,一维扫描线是十分重要、也是十分套路的,学过和没学过的差距很明显。希望大家认真学习。

例1

有n个点,m组[ai,bi),求所有m个区间重叠的部分有多少个位置。其中m<=1e6,0<=ai<bi<=n<=1e9

可以用扫描线思想。

扫描线可以看作是差分的优化,差分处理对a[s]~a[t]中的元素+1的方法:d[s]+=1, d[t+1]-=1
但差分求值需要遍历整个d数组,时间、空间复杂度为O(n),n为被修改数组的长度
如果长度太长(比如1e9),就会空间过大+超时

这时就可以上扫描线,其核心思想就是把差分在数组上的操作抽象成对数轴上若干个点的操作
例如:差分方法:d[s]+=1,d[t+1]-=1; 扫描线方法:在数组尾部插入 {s,+1} {t+1,-1}

这样只要对存储点修改的数组进行遍历,再用累加变量累加修改值,就能实时得到当前点的值
同时,当前修改点和上一个修改点之间的所有数组元素,其值都是上一个修改点位置的累加变量
这样时间、空间复杂度都为O(m),m为修改点的个数,肯定能过

扫描线的注意事项:
1.存储点修改的数组,用vector方便,但有常数过大而超时的风险。建议在m比较大的时候使用普通数组

2.存储所有修改点之后一定要按照修改位置从小到大排序,不然就乱了

3.排序后还要处理同一个点多次修改的重复问题,有三种主流的解决方案:
1)在遍历所有点时,先对它和它之后所有修改下标一致的点进行合并,再计算。这是比较稳妥的方法

2)在求最值等一些特殊的题目中(比如例1),重复累加并不影响操作,可以根据排序让它只有在同一个点都累加完后,才出现对答案有贡献的值
比如,求最大值。可以排序时先按照下标升序排序,再把-1操作排在+1前面,这样遍历时先减再加,不会影响最大值的求解。

3)使用万能的map。map就像一个桶数组一样,可以很方便地把所有点的修改都累加到一块去。还能自动按照键升序排序,绝对是为扫描线量身定做的梦想中的容器!
但这样虽然方便,会有因常数过大而超时的风险(map理论复杂度为O(nlogn),但这个log很大)

Code:

#include <bits/stdc++.h>
using namespace std;struct Node{int pos, add; // 位置pos,贡献addfriend bool operator < (Node p1, Node p2){ // 先按照位置升序排序,再按照贡献升序排序(减法要排在加法前面,不然会导致先加得大了,然后求max时答案出错)if(p1.pos != p2.pos) return p1.pos < p2.pos;return p1.add < p2.add;}
};void solve()
{int n;cin >> n;vector <Node> A;for(int i = 0, b, t; i < n; i ++){cin >> b >> t;A.push_back({b, 1});A.push_back({t, -1}); // 注意大炮的范围是[b,t),所以差分的-1应该在t位置上,而不是t+1}sort(A.begin(), A.end());int ans = 1, d = 0; // ans是答案,d是差分值for(auto it : A){d += it.add;ans = max(ans, d);}cout << ans << "\n";
}signed main()
{ios :: sync_with_stdio(false), cin.tie(0), cout.tie(0);solve();return 0;
}

例2

n n n 个点, m m m 个修改,每次修改都对[l,r]区间内的每个点+1。1<=n,l,r<=1e9 1<=m<=1e6 1<=a[i]<=1e6
求 Σcnt[i]*a[i] 其中cnt[i]表示点的值为i的个数,a[i]表示每个值为i的点对答案的贡献。

这道题需要求区间修改后n个点中每一个值的个数。
记得前面说过“同时,当前修改点和上一个修改点之间的所有数组元素,其值都是上一个修改点位置的累加变量”。

由此,能知道两个修改点之间的所有点的值,又可以容易地计算出两个修改点之间差了多少个点。就可以统计cnt数组了。(具体看代码里pre变量的使用)

但这道题的难点不在于扫描线,而是出题人……
1.不能给所有变量都开long long,这样会因为常数过大而超时(因为long long占8个字节,int占四个字节,所以long long平均每次运算次数都是int的两倍)

2.如果你图方便用map存储所有的修改点,以为这样就不用考虑重复的问题了。但抱歉,出题人也会卡

在OI赛制下,很少有人能注意到上面两个坑点。码风朴实,没有那么多花里胡哨的同学反而因为不用STL而占据优势。

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxm = 1e6 + 5;int n, m;
int a[maxm], cnt[maxm]; // cnt:记录个数的桶数组struct Node{int p, t; // 表示p位置的修改为tfriend bool operator < (Node p1, Node p2){return p1.p < p2.p;}
};
vector <Node> d; // 差分数组void solve()
{cin >> n >> m;for(int i = 1; i <= m; i ++) cin >> a[i];for(int i = 1, l, r; i <= m; i ++){cin >> l >> r;d.push_back({l, 1}); d.push_back({r + 1, -1}); // 进行差分}sort(d.begin(), d.end()); // 排序int pre = -1; // 上一个差分的点int ans = 0; // 累加变量for(int i = 0; i < d.size(); i ++){int pos = i;while(d[i].p == d[i + 1].p){ // 把同一个位置的所有修改都累加起来,这样便于统计答案d[pos].t += d[i + 1].t;++ i;}if(pre != -1){cnt[ans] += (d[pos].p - 1) - pre + 1; // 累加的答案区间是[pre,d[].p)}ans += d[pos].t; // 累加pre = d[pos].p; // 记录前一个端点}ll tot = 0;for(int i = 1; i <= 1e6; i ++){tot += 1LL * a[i] * cnt[i]; // 对于不存在的,cnt[i]一定=0,其不会被记录}cout << tot << '\n';
}signed main()
{ios :: sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);solve();return 0;
}

【困难】二维扫描线(计算几何)

先咕一下,等会了再补
https://blog.csdn.net/Zz_0913/article/details/135128515

End

感谢大家的观看!拜拜ヾ(•ω•`)o

推销个人洛谷账号:ylch,洛谷博客:YLCHUP

相关文章:

【2024最新】C++扫描线算法介绍+实战例题

扫描线介绍&#xff1a;OI-Wiki 【简单】一维扫描线&#xff08;差分优化&#xff09; 网上一维扫描线很少有人讲&#xff0c;可能认为它太简单了吧&#xff0c;也可能认为这应该算在差分里&#xff08;事实上讲差分的文章里也几乎没有扫描线的影子&#xff09;。但我认为&am…...

语言主要是一种交流工具,而不是思维工具?GPT5何去何从?

引言 在人工智能领域&#xff0c;特别是大语言模型&#xff08;LLM&#xff09;的发展中&#xff0c;语言和思维的关系一直是一个备受关注的话题。近期&#xff0c;麻省理工学院&#xff08;MIT&#xff09;在《Nature》杂志上发表了一篇题为《Language is primarily a tool f…...

传感器标定(三)激光雷达外参标定(lidar2ins)

一、数据采集 1、LiDAR 传感器的 LiDAR PCD 数据 2、来自 IMU 传感器的姿势文件 3、手动测量传感器之间外部参数初始值并写入的 JSON 文件 二、下载标定工具 //总的git地址&#xff1a; https://github.com/PJLab-ADG/SensorsCalibration git地址&#xff1a; https://githu…...

【漏洞复现】Crocus系统—Download 文件读取

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 Crocus系统中的Download文件读取漏洞允许未经身份验证的攻击者通过特定请求读取系统上的任意文件。Crocu…...

游戏开发面试题1

说说对单例模式的了解 单例模式&#xff08;Singleton Pattern&#xff09;是一种设计模式&#xff0c;其目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。这在某些情况下非常有用&#xff0c;比如需要一个唯一的配置管理器、日志记录器、或资源管…...

线程池笔记

笔记梳理 前言.PHONYC标准库头文件C/C通用或C特有头文件mkdirc_str()snprintfvsnprintfumaskopen函数可变参数列表va_startva_endfunctionalstatic_castpthread_cond_init_threads.emplace_backstd::bindstd::placeholdersThreadPool(const ThreadPool<T> &tp) dele…...

Go语言基础数据类型、变量及自增语法

本文内容为Go语言的基础数据类型、变量定义和赋值及自增语法介绍。 目录 基础数据类型 变量 先定义后赋值 定义时直接赋值 自动推导定义赋值 平行赋值 自增语法 总结 基础数据类型 int,int8 intl6, int32, int64 uint8... uint64 float32,float64 true/false 变量 …...

ES6-ES13符号:单双引号、变量的解构赋值、占位符 、字符串模版`${} `、扩展运算符...、?,??,_,||=,=,in

原型、this、闭包&#xff0c;for四类循环&#xff0c;ES6-14&#xff08;2023&#xff09;_es6-es14-CSDN博客 目录 查看ES版本 单双引号&#xff1a;无区别 变量的解构赋值&#xff1a;声明变量被数组/对象中的元素赋值 推荐用const&#xff0c;因为是从其他地方获取值 …...

【远景能源25届校招PI测评】题型深度解析与应试策略

摘要&#xff1a; 远景能源作为新能源行业的领军企业&#xff0c;其校园招聘备受瞩目。本文将深入分析25届远景能源校招的PI测评题型&#xff0c;为求职者提供全面的备考指南。 正文&#xff1a; 尊敬的求职者们&#xff0c;您是否正准备迎接远景能源的校招挑战&#xff1f;P…...

关于Qt Creator 使用Qt Quick的Design模式设置

关于使用Qt Quick的Design模式设置&#xff1a; 如描述所言&#xff1a; 如果使用Design模式打开qml文件失败显示如下&#xff1a; 首先确认自己是否安装了Qt Design Studio 如果安装了仍然不显示&#xff0c;则需要勾选下面三个地方才能用Design模式打开.ui.qml文件&#…...

Spring常见问题一:IOC和DI

IOC和DI IOC和DI之间到底是什么关系&#xff1f; 什么是依赖关系&#xff1f;依赖关系会带来什么问题&#xff1f;Spring是怎么来支持依赖注入的&#xff1f; 引言 在现代软件开发中&#xff0c;面向对象编程&#xff08;OOP&#xff09;已经成为主流编程范式。然而&#xff0…...

LabVIEW红外热波图像缺陷检

开发使用LabVIEW开发的红外热波图像缺陷检测系统。该系统结合红外热像仪、工业相机和高效的数据采集硬件&#xff0c;实现对工件表面缺陷的自动检测和分析。通过LabVIEW的强大功能&#xff0c;系统能够实时采集、处理和显示红外热波图像&#xff0c;有效提高了检测的精度和效率…...

c#与欧姆龙PLC通信——如何更改PLC的IP地址

前言 我们有时候需要改变欧姆龙Plc的ip地址,下图有两种更改方式,一种是已知之前Plc设置的Ip地址,还有一种是之前不知道Pl的Ip地址是多少,下面分别做介绍。 1、已知PLC的IP地址的情况下更改地址 假设已知PLC的Ip地址,比如本文中PLC的IP为192.168.1.2,我首先将电脑的IP地…...

[Spring Boot]定时任务因系统时间修改之后无法执行

问题描述 当Spring Boot启动时&#xff0c;当前时间为2024-01-01 00:00:00。 此时你创建了任务&#xff1a; 每10秒钟触发一次定时任务 Scheduled(cron "0/10 * * * * ? ") public void scheduledTask() { }此时你手动修改了系统时间&#xff0c;修改为2023-12-0…...

【棋盘上的战舰】python刷题记录

目录 小前言 思路&#xff1a; 上代码 lucky ending 小前言 经过漫长的停更周期-----1个月 我决定铁血回归&#xff01;&#xff01;&#xff01; 思路&#xff1a; 两层for循环暴力最快了这种小小范围题&#xff0c;主要是第一行和第一列的边界处理&#xff0c;我分为…...

NoSQL 之Redis集群

Redis集群 主从复制 主从复制&#xff08;Replication&#xff09;是 Redis 中一种基本的高可用架构模式&#xff0c;适用于简单的读写分离需求和基本的故障恢复。在主从复制中&#xff0c;一个 Redis 主节点可以拥有多个从节点&#xff0c;主要特点包括&#xff1a; 角色定义&…...

ES13的4个改革性新特性

1、类字段声明 在 ES13 之前,类字段只能在构造函数中声明, ES13 消除了这个限制 // 之前 class Car {constructor() {this.color = blue;this.age = 2...

Flutter EasyRefresh:介绍与使用指南

什么是 Flutter EasyRefresh&#xff1f; Flutter EasyRefresh 是一个强大的下拉刷新和上拉加载组件&#xff0c;用于构建流畅且高效的 Flutter 应用程序。它提供了多种自定义配置和动画效果&#xff0c;使开发者可以轻松实现列表的刷新和加载功能。 主要功能 支持下拉刷新和…...

链表的回文结构(链表的中间节点+反转链表)

链表的回文结构 一.链表的中间节点思路1&#xff1a;暴力求解思路2&#xff1a;快慢指针 二.返回倒数第k个节点思路1&#xff1a;暴力求解思路2&#xff1a;快慢指针 三.反转链表思路1&#xff1a;头插法思路2&#xff1a;反转指针的指向 四.链表的回文结构思路1&#xff1a;利…...

汇编学习基础知识【记录】

前言 又是快乐的学习汇编的一天&#xff0c;时间如白驹过隙&#xff0c;抓紧时间&#xff0c;在学习能力最好的年纪多学习一些知识&#xff0c;朝着美好生活而奋斗&#xff01;哈哈哈 参考文章&#xff1a; https://blog.csdn.net/Z_H_Z_0/article/details/106574292 知识补…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...