《算法笔记》离散化
文章目录
此题第一次看确实没看懂,所以此处略作分析,为什么要离散化呢,因为存储的下标实在太大了,如果直接开这么大的数组,根本不现实,第二个原因,本文是数轴,要是采用下标的话,可能存在负值,所以也不能,所以有人可能会提出用哈希表,哈希表可以吗?答案也是不可以的,因为哈希表不能像离散化那样缩小数组的空间,导致我们可能需要从-e9遍历到1e9(此处的含义就是假如我们需要计算1e-9和1e9区间内的值,那我们需要从前到后枚举,无论该值是否存在),因为哈希表不能排序,所以我们一般不能提前知道哪些数轴上的点存在哪些不存在,所以一般是从负的最小值到正的最大值都枚举一遍,时间负责度太高,于是就有了本题的离散化。
离散化的本质,是映射,将间隔很大的点,映射到相邻的数组元素中。减少对空间的需求,也减少计算量。
其实映射最大的难点是前后的映射关系,如何能够将不连续的点映射到连续的数组的下标。此处的解决办法就是开辟额外的数组存放原来的数组下标,或者说下标标志,本文是原来上的数轴上的非连续点的横坐标。
此处的做法是是对原来的数轴下标进行排序,再去重,为什么要去重呢,因为本题提前考虑了前缀和的思想,其实很简单,就是我们需要求出的区间内的和的两端断点不一定有元素,提前加如需要求前缀和的两个端点,有利于我们进行二分搜索,其实二分搜索里面我们一般假定有解的,如果没解的话需要特判,所以提前加入了这些元素,从而导致可能出现重复元素。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
int a[300010];
int s[300010];
vector<int > alls; //用于存放所有需要离散化的数
vector<PII > add; //用于存放要累加的x
vector<PII > query; //用于存放l ,r
int n, m; //n个操作, m次询问
int find(int x) //对于x 找到其映射到alls里面的坐标
{
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;
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i++){
int x, c;
scanf("%d%d", &x, &c);
add.push_back({x, c});
alls.push_back(x); //存入需要离散化的x
}
for(int i = 0; i < m; i++){
int l, r;
scanf("%d%d", &l, &r);
query.push_back({l, r});
alls.push_back(l);
alls.push_back(r); //存入需要离散化的l, r
}
sort(alls.begin(), alls.end());
alls.erase(unique(alls.begin(), alls.end()), alls.end()); //对alls去重 对于重复的数字没有意义
for(vector<PII>::iterator it = add.begin(); it != add.end(); it++){
int x = find(it->first);
a[x] += it->second;
}
// for(auto item : add){
// int x = find(item.first);
// a[x] += item.second;
// }
for(int i = 1; i <= alls.size(); i++)
s[i] = s[i - 1] + a[i];
for(vector<PII >::iterator item = query.begin(); item != query.end(); item++){
int l = find(item->first);
int r = find(item->second);
int res = s[r] - s[l - 1];
cout << res << endl;
}
// for(auto item : query){
// int l = find(item.first);
// int r = find(item.second);
// int res = s[r] - s[l - 1];
// cout << res << endl;
// }
return 0;
}
转载链接:https://www.acwing.com/solution/content/2321/