【算法训练(day7)】区间和并,离散化数组模板

news2025/1/11 10:05:25

目录

一.区间和并

二 .离散化数组


一.区间和并

 问题:给定 n个区间 [li,ri],要求合并所有有交集的区间。注意如果在端点处相交,也算有交集。输出合并完成后的区间个数。例如:[1,3][1,3] 和 [2,6][2,6] 可以合并为一个区间 [1,6][1,6]。

  1. 实现功能及思路:将所有含有交集的区间和并。需要用到有序的性质。我们把每段的起始位置进行排序。当我们合并两端不同的区间时有可能会出现三种情况。第一段区间和第二段区间没有交集,或者是第一段区间包含整个第二段的区间。又或者是第一段区间包含了部分第二段区间。我们只需要分别处理这三种情况并记录下来就可以完成区间和并。第一种情况的时候没有交集所以两端区间无法合并,第二种情况因为第一段包含了第二段所以第一段区间就是合并后的区间。第三种情况,从第一段的起始位置,到第二段的结束位置就是合并后的新区间的位置。
  2. 代码实现:
    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    void merge(vector<pair<int, int>>& opr)
    {
        vector<pair<int, int>> ret;
        sort(opr.begin(), opr.end());   //需要借助有序的性质
    
        int st = -1e9 - 10, ed = -1e9 - 10;
        for (auto pt : opr)
        {
            if (ed < pt.first)             //处理无法合并的部分 st————————ed
            {                               //                                 st——————ed
                if (ed != -1e9 - 10)        //当前物件直接加入结果,继续遍历后序数组。
                {
                    ret.push_back({ st,ed });
                }
                st = pt.first;
                ed = pt.second;
            }
            else
            {
                ed = max(ed, pt.second);   //这里处理的是两种情况      1.st——————————ed    2.st——————————ed
                                            //                            st————ed              st————————ed
            }
        }
        if (ed != -1e9 - 10)
        {
            ret.push_back({ st,ed });
        }
        cout << ret.size();
        return;
    }
    int main()
    {
        int n = 0;
        cin >> n;
        vector<pair<int, int>> opr;
        for (int i = 0; i < n; i++)
        {
            int l, r;
            cin >> l >> r;
            opr.push_back({ l,r });
        }
        merge(opr);
        return 0;
    }

二 .离散化数组

问题:假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。现在,我们首先进行 n 次操作,每次操作将某一位置 x上的数加 c。接下来,进行 m次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r]之间的所有数的和。

 

  1. 实现功能及思路:先前我们处理过前缀和问题。当时要求前缀和的数据是连续的。且数量不多。如果要求的前缀和数据不是连续的且分散的很远(有效数据之间有若干0)的话再用之前的算法效率就会很低。因为如果继续按照之前的算法我们是要遍历所有数据所有范围的。这时候我们就可以用一个离散化数组。也就是哈希映射,把原先分散的值的下标重新映射到一个新的连续的数组上。这时候就可以继续正常求前缀和了。

    数据范围

  2. 细节处理:  虽然我们只有1e5个数据但是因为在进行前缀和的预处理的时候,我们的范围包括查询的次数,所以实际应该是n+2m。 同时构建哈希映射数组的时候不单单只能包含插入数据的映射关系,还要包含查询数据的映射关系,因为我们查询的时候也需要去离散数组里去确定范围。    对插入和查询的下标的排序是在map里进行的 
  3. 代码实现:
    #include <cstdio>
    #include <iostream>
    #include <vector>
    #include <map>
    
    using namespace std;
    //离散化数组+前缀和求解(因为题目的数据范围很广但数据量很稀疏,若是直接用前缀和求解效率过于低下,所以先用哈希把数组的有效元素位置哈希映射后形成一个较小的离散化数组后在使用前缀和)
    const int N = 3e5 + 10;  //范围需要提前考虑前缀和的预处理
    int a[N];//存放构造出来的离散化数组,用来后需求前缀和
    int b[N];//存放根据离散化数组构建出来的前缀和
    vector<pair<int, int>> add, que;//所有增加操作和查询操作数组。 
    map<int, int> repst;//存放构造的哈希数组和实际值之间的对应关系
    int main()
    {
        //构建离散化数组和真实数组的关系
        int n = 0,m = 0;
        cin >> n >> m;
        for (int i = 0; i < n; i++)  //保存所有的插入操作(插入位置和插入值)
        {
            int x,c;   //x是真实位置,c是插入值
            cin >> x >> c;
            add.push_back({ x,c }); 
            repst[x] = 0;   //i就是新的下表
        }
    
        for (int j = 0; j < m; j++)  //保存所有的查询操作(查询的位置也要构建对应关系,因为我们要到离散化数组里去找值,不能用原值去找)
        {
            int l, r;
            cin >> l >> r;
            que.push_back({ l,r });
            repst[l] = 0;
            repst[r] = 0;
        }
        int pos = 1;//映射新下标
        for (auto &pt : repst)
        {
            pt.second = pos++;
        }
        //插入修改操作
        for (auto input : add)
        {
            int pt = repst[input.first];//离散化后的新下标
            a[pt] += input.second;
        }
        //前缀和预处理
        for (int i = 1; i <= repst.size(); i++)  //repst.size()表示map repst中不同元素的个数,也就是离散化后数组的大小。因此,for循环的循环变量i的取值范围为[1, repst.size()],对于每个i,都计算出a[1]到a[i]的前缀和计算前缀和的范围不能只是插入值的范围,不然就会少计算那些没离散化的0.
        {
            b[i] = a[i] + b[i - 1];
        }
        //处理询问
        for (auto output : que)
        {
            int l = repst[output.first];//离散化后的新下标
            int r = repst[output.second];//离散化后的新下标
    
            cout << b[r] - b[l - 1] << endl;
        }
        return 0;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/602282.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

htmlCSS-----CSS介绍与样式书写

目录 前言&#xff1a; 1. CSS是什么 2. CSS书写样式 (1)行内样式 (2)内部样式 3.外部样式 4.三者之间的比较 前言&#xff1a; 前面我们学习了HTML的相关标签和框架写法&#xff0c;那我们在了解这些标签用法了之后就要学会怎么去通过相关方法来使得界面美化处理&#xf…

06 Redis分布式锁

常见面试问题 Redis除了拿来做缓存&#xff0c;你还见过基于Redis的什么用法&#xff1f;Redis 做分布式锁的时候有需要注意的问题&#xff1f;如果是 Redis 是单点部署的&#xff0c;会带来什么问题&#xff1f;那你准备怎么解决单点问题呢&#xff1f;集群模式下&#xff0c…

LeetCode刷题集(七)(2315.统计星号)

&#x1f626;学习目标&#xff1a;拿下LeetCode2315.统计星号题目 &#x1f624; 学完本章节知识即可掌握本题&#xff01; 学习内容&#xff1a;LeetCode2315.统计星号 &#x1f624;题目&#xff1a;给你一个字符串 s &#xff0c;每 两个 连续竖线 ‘|’ 为 一对 。换言之&…

知识图谱涉及技术点分析

文章目录 数据从哪里来为什么通常将知识图谱划分到NLP领域&#xff1f;常用NLP技术点分析只是NLP任务吗&#xff1f;graph embedding知识融合业务还是算法&#xff1f;知识图谱组成 数据从哪里来 是手动提取关系吗&#xff1f;数据很多&#xff0c;关系确难涉及大量NLP技术关系…

Ansible基础五——条件语句、循环语句、handlers、任务失败处理

文章目录 一、 循环语句1.1 单量循环1.2 多量循环1.3 老版本用法1.4 loopregister 二、条件判断2.1 根据变量状态判断2.2 根据变量是否存在判断2.3 根据事实判断2.4 多条件判断2.4.1 and用法2.4.2 or用法 2.5 循环判断2.6 根据上个任务结果判断 三、handlers处理程序四、任务失…

5月《中国数据库行业分析报告》正式发布,首发时序、实时数据库两大【全球产业图谱】

为了帮助大家及时了解中国数据库行业发展现状、梳理当前数据库市场环境和产品生态等情况&#xff0c;从2022年4月起&#xff0c;墨天轮社区行业分析研究团队出品将持续每月为大家推出最新《中国数据库行业分析报告》&#xff0c;持续传播数据技术知识、努力促进技术创新与行业生…

ubuntu20安装xrdp以及解决黑屏问题

1、安装xrdp sudo apt-get install xrdp 2、将xrdp用户加入到如下用户组 sudo adduser xrdp ssl-cert 3、重启xrdp sudo service xrdp restart 4、打开windows远程面&#xff0c;连接&#xff0c;如果出现黑屏 sudo -s sudo vim /etc/xrdp/startwm.sh 加入如下内容&#xff…

攻防世界-web-Web_php_unserialize

1. 题目描述&#xff1a;查看以下代码&#xff0c;获取flag 2. 思路分析 从代码中不难看出&#xff0c;这里共有三个地方需要绕过 2.1 __wakeup函数&#xff1a;若在对象的魔法函数中存在的__wakeup方法&#xff0c;那么之后再调用 unserilize() 方法进行反序列化之前则会先…

数据分析概述

数据分析概述 数据的性质数据的概念数据与信息的区别和联系 数据的类型按照度量尺度分按时间状况分 什么是数据分析数据分析的重要性数据分析的内容数据分析作用 数据分析的基本流程典型的数据分析的流程 数据分析方法对比分析法分组分析法定量数据分布分析——具体事例 结构分…

上海亚商投顾:沪指高开高走 地产股迎来久违反弹

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 三大指数今日高开高走&#xff0c;沪指午后涨近1%&#xff0c;深成指、创业板指涨超1.2%&#xff0c;上证50盘中大…

惠更斯定理和格林定理

惠更斯原理和格林定理 惠更斯原理显示了表面上的波场如何决定表面 S S S外的波场。惠更斯在17世纪启发性地表达了这一概念。但这个想法的数学表达是由于19世纪的乔治格林。这一概念可以在数学上表达为标量波和矢量波。矢量波情形的推导与标量波情形是同态的。但是标量波情况下…

少儿编程python-一级

少儿编程python 文章目录 前言CSP-J与CSP-S少儿编程证书含金量排名&#xff08;国家承认的少儿编程证书&#xff09;非专业级软件能力认证&#xff08;CSP-J/S&#xff09;青少年编程能力等级测试&#xff08;CPA&#xff09;蓝桥杯青少年信息技术等级考试全国青少年软件编程等…

造船厂事故/风险(背景+官方统计数据)

造船厂事故/风险&#xff08;背景官方统计数据&#xff09; 船厂工地常见事故船厂事故:发人深省的伤害统计船厂工地常见的风险有哪些? 造船业是周期性的、资本密集型的行业。更严格的环境法规于2020年初生效&#xff0c;引发了对抑制船舶废气硫排放技术的需求。与此同时&#…

数据标记工具

检测分割标定 labelstudio https://labelstud.io/sudo apt install libpq-dev python3-devconda activate paddle_envpip install label-studiolabel-studio startlabel-studio --data-dir /data/data_label_studio<View><Image name"image" value"$im…

【shiro】shiro整合JWT——2.如何整合

前言 shiro整合JWT系列&#xff0c;主要记录核心思路–如何在shiroredis整合JWTToken。 上一篇中&#xff0c;我们知道了需要创建JwtToken、JwtUtil、JwtFilter。 该篇主要讲如何在shiro框架中&#xff0c;配置Jwt。 ps&#xff1a;本文主要以记录核心思路为主。 1、ShiroCon…

如何零基础自学黑客?

我经常会看到这一类的问题&#xff1a; 学习XXX知识没效果&#xff1b;学习XXX技能没方向&#xff1b;学习XXX没办法入门&#xff1b; 给大家一个忠告&#xff0c;如果你完全没有基础的话&#xff0c;前期最好不要盲目去找资料学习&#xff0c;因为大部分人把资料收集好之后&…

Android中的WorkManager

Android中的WorkManager 在后台运行任务会消耗设备有限的资源&#xff0c;如RAM和电池。这可能会导致用户体验不佳。例如&#xff0c;后台任务可能会降低设备的电池寿命或用户在观看视频、玩游戏、使用相机等时可能会遇到设备性能不佳的情况。 为了提高电池性能&#xff0c;An…

关于人力资源管理职能,你需要知道的事

每个成功的企业都有一个称职的人力资源部门。它是任何企业的重要组成部分&#xff0c;是员工和管理层之间的纽带。人力资源涵盖影响组织人员的所有任务&#xff0c;从基本的人力资源活动到战略决策。 对于任何希望可持续发展的企业来说&#xff0c;人力资源管理职能的重要性不…

0802数量积向量积混合积-向量代数与空间解析几何

文章目录 1 两向量的数量积1.1 引例1.2 定义1.3 推论1.4 运算规律1.4 数量积的坐标表示 2 两向量的向量积2.1 定义2.2 重要结论2.3 几何意义&#xff08;向量积模&#xff09;2.4 向量积的运算规律2.5 向量积的坐标表示 3 向量的混合积3.1 混合积的定义3.2 混合积的坐标表示3.3…

初识报表引擎-FineReport

简介 提到报表引擎大家可能都会说帆软。目前商用的比较突出的两个报表引擎&#xff1a;分别是帆软FineReport、RDP报表引擎&#xff0c;其中帆软功能突出且非常完整但是价格较高&#xff0c;RDP功能相对完整但是不够强大貌似还有些BUG&#xff0c;不过价格很低。就目前的情况来…