基础算法-【离散化】

这篇具有很好参考价值的文章主要介绍了基础算法-【离散化】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

离散化的本质:是建立了一段数列到自然数之间的映射关系(value -> index),通过建立新索引,来缩小目标区间,使得可以进行一系列连续数组可以进行的操作比如二分,前缀和等…

相应的算法模板:

    vector<int> alls; // 存储所有待离散化的值
    sort(alls.begin(), alls.end()); // 将所有值排序
    alls.erase(unique(alls.begin(), alls.end()), alls.end());    // 去掉重复元素
    
    // 二分求出x对应的离散化的值
    int find(int x)
    {
        int l = 0, r = alls.size() - 1;
        while (l < r)
        {
            int mid = l + r >> 1;
            if (alls[mid] >= x) r = mid;
            else l = mid + 1;
        }
        return r + 1;
    }

题目:

基础算法-【离散化】,# 算法基础,算法

离散化首先需要排序去重:

1. 排序:sort(alls.begin(),alls.end())
2. 去重:alls.earse(unique(alls.begin(),alls.end()),alls.end());

unique()函数的底层原理

vector<int>::iterator unique(vector<int> &a) {
    int j = 0;
    for (int i = 0; i < a.size(); ++i) {
        if (!i || a[i] != a[i - 1])//如果是第一个元素或者该元素不等于前一个元素,即不重复元素,我们就把它存到数组前j个元素中
            a[j++] = a[i];//每存在一个不同元素,j++
    }
    return a.begin() + j;//返回的是前j个不重复元素的下标
}

由于本题可能有多组数据是针对同一个数组下标操作的,因此我们可以将所有用到的数组下标装在一个下标容器alls内去重,然后再逐一为相同的数组下标增加数值c,再通过对应前缀和相减求得区间 l~r 之间的数的值

代码详解:文章来源地址https://www.toymoban.com/news/detail-559217.html

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

typedef pair<int,int> PII;

const int N = 300010;

int n,m;
int a[N],s[N];


vector<int> alls;//存入下标的容器
vector<PII> add,query;//add增加容器,存入对应下标和增加值的大小
//query存入需要计算下标区间和的容器

int find(int x){
    int l = 0,r = alls.size() - 1;
    while(l < r){
        int mid = l + r >> 1;
        if(alls[mid] >= x){
            r = mid;
        }
        else{
            l = mid + 1;
        }
    }
    
    return r + 1;//因为要使用前缀和,其下标要+1可以不考虑边界问题
    
}


int main(){
    cin >> n >> m;
    for(int i = 0;i < n;i ++ ){
        int x,c;
        cin>> x >> c;
        add.push_back({x,c});//存入下标以及对应的数值c
        
        alls.push_back(x);//存入数组的下标x = add.first
        
    }
  
    for(int i = 0;i < m;i ++ ){
         int l,r;
         cin >> l >> r;
         query.push_back({l,r});
         
         alls.push_back(l);//存入区间的左右下标
         alls.push_back(r);
         
}

//区间去重
sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(),alls.end()),alls.end());



//处理插入
for(auto item : add){
    int x = find(item.first);//将add容器的add.secend值存入数组a[]当中
    a[x] += item.second;//在去重之后的下标集合alls内寻找对应的下标并添加数值
}

//预处理前缀和
for(int i = 1;i <= alls.size();i ++ ) s[i] = s[i - 1] + a[i];

//处理查询
for(auto item : query){
    int l = find(item.first) , r = find(item.second);//在下标容器中查找对应的左右两端[l~r]下标,然后通过下标得到前缀和相减再得到区间a[l~r]的和
    cout << s[r] - s[l - 1] << endl;
}

 return 0;
}

到了这里,关于基础算法-【离散化】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 位运算 离散化 区间和算法

    首先知道一个概念: 一个正整数的负数等于其按位取反后+1 -x = ~x + 1 举个例子:3 而我们通过 (x ~x + 1)或(x -x) 就可以得到二进制数最后一位1的大小。 举个例子: 题目链接 题目描述 给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。 输入格式 第一行

    2024年01月20日
    浏览(23)
  • C++ 离散化 算法 (详解)+ 例题

    1、性质 把 无限空间 中有限的个体映射到 有限的空间 中去,以此提高算法的空间效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的压缩。 适用范围: 数的跨度很大,用的数很稀疏 例如:值域:1~10^9, 个数:10^5,值域很大,但是用到个数相对

    2024年02月19日
    浏览(38)
  • 【Educoder离散数学实训】关系基础

    题有点多,能聊的不多。有些题还是比较有价值的 就单独说几个题,代码放在最后。所有函数都改成自己写的了,没准比答案给的好读一点? T1 求给定集合的对角线关系(diagonal relation) 我觉得如果卡住的话,第一关会是一个大坎。 因为我们并不知道他到底在说啥,于是我

    2024年02月07日
    浏览(42)
  • 【matlab算法原理详解】离散非周期信号频谱分析的MATLAB算法实现

    1 引言 介绍四种不同类型信号的频谱变化规律中的一种,即离散非周期信号。在从理论上掌握其频谱变化规律的基础上,着重讨论如何应用离散傅里叶变换DFT对其频谱进行分析,针对具体实例,通过MATLAB编程采用FFT算法实现对其频谱的计算,并和理论值比较,作了相应的误差

    2023年04月13日
    浏览(31)
  • 洛谷题单--算法[2-1] 前缀和、差分与离散化

    目录 0.铺垫学习:p1115最大子段和--前缀和+贪心+DP 1.p1719最大加权矩形--前缀和+贪心+DP+矩阵压缩 原题链接: P1115 最大子段和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 原题: 题目描述 给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。 输入格式 第

    2024年02月22日
    浏览(34)
  • 离散数学 --- 图论基础 --- 子图和补图,握手定理

    1.生成子图:点集合不变,边集合是原图的边集合的子集 2.导出子图:点集合是原图点集合的非空子集V,然后再在原图的边集合中找到两个端点均在点集合V中的边元素,并将这些边元素称成一个新的边集合,得到的这个边集合就是导出子图的边集合 (点集合V和得到的新的边

    2023年04月08日
    浏览(35)
  • Python实现离散选择Logit模型(Logit算法)项目实战

    说明:这是一个机器学习实战项目(附带 数据+代码+文档+视频讲解 ),如需 数据+代码+文档+视频讲解 可以直接到文章最后获取。 Logit模型(Logit model,也译作“评定模型”,“分类评定模型”,又作Logistic regression,“逻辑回归”)是离散选择法模型之一,属于多重变量分析

    2024年01月21日
    浏览(30)
  • Python实现离散选择多项式对数模型(MNLogit算法)项目实战

    说明:这是一个机器学习实战项目(附带 数据+代码+文档+视频讲解 ),如需 数据+代码+文档+视频讲解 可以直接到文章最后获取。 多项式对数模型是离散选择模型的一种。 本项目通过MNLogit算法来构建多项式对数模型。   本次建模数据来源于网络(本项目撰写人整理而成),数

    2024年01月23日
    浏览(38)
  • Python实现离散选择负二项式模型(NegativeBinomial算法)项目实战

    说明:这是一个机器学习实战项目(附带 数据+代码+文档+视频讲解 ),如需 数据+代码+文档+视频讲解 可以直接到文章最后获取。 离散选择负二项式模型是一种统计和经济计量模型,它结合了离散选择理论与负二项分布的特点来分析计数型的离散决策变量。在实际应用中,

    2024年01月21日
    浏览(32)
  • 基于改进的离散PSO算法的FJSP的研究(Python代码实现)

    💥 💥 💞 💞 欢迎来到本博客 ❤️ ❤️ 💥 💥 🏆 博主优势: 🌞 🌞 🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳ 座右铭: 行百里者,半于九十。 📋 📋 📋 本文目录如下: 🎁 🎁 🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Python代码实现 文

    2024年02月09日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包