在 C++ 中,离散化算法是将一个集合中的元素映射到连续的整数值的过程。这个过程通常用于解决需要对元素进行排序、计数或其他操作时,但元素的取值范围很大或有重复值的情况。
下面是一种常用的离散化算法的实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> discrete(vector<int>& nums) {
// 复制原始数组并排序
vector<int> sortedArr = nums;
sort(sortedArr.begin(), sortedArr.end());
// 去重
sortedArr.erase(unique(sortedArr.begin(), sortedArr.end()), sortedArr.end());
// 离散化映射表
vector<int> mapping(nums.size());
// 遍历原始数组,查找每个元素在排序后数组中的位置
for (int i = 0; i < nums.size(); i++) {
mapping[i] = lower_bound(sortedArr.begin(), sortedArr.end(), nums[i]) - sortedArr.begin();
}
return mapping;
}
int main() {
vector<int> nums = {10, 5, 3, 7, 10, 7};
vector<int> mapping = discrete(nums);
cout << "原始数组:";
for (int num : nums) {
cout << num << " ";
}
cout << endl;
cout << "离散化后的映射数组:";
for (int num : mapping) {
cout << num << " ";
}
cout << endl;
return 0;
}
运行结果:
```
原始数组:10 5 3 7 10 7
离散化后的映射数组:1 0 4 2 1 2
```
在这个例子中,我们将原始数组 `{10, 5, 3, 7, 10, 7}` 进行离散化,最终得到的映射数组为 `{1, 0, 4, 2, 1, 2}`。离散化后,原始数组中的 10 映射为 1,5 映射为 0,3 映射为 4,7 映射为 2。离散化后的映射数组中的元素就可以用来代表原始数组中的元素了。
在离散化算法的实现中,我们首先复制并排序原始数组,然后去除排序后数组中的重复元素。然后,我们遍历原始数组,利用 `lower_bound()` 函数查找每个元素在排序后数组中的位置,并将找到的位置作为映射数组中的元素。最后返回映射数组。
离散化算法的时间复杂度为 O(nlogn),其中 n 是原始数组的大小。这是因为算法需要对原始数组进行排序,并且在查找每个元素的位置时使用了二分查找。
AcWing练习-区间和
#include<bits/stdc++.h>
using namespace std;
const int N=300010;
int a[N],s[N];
int n,m;
vector<int> alls;
vector<pair<int,int>> query,add;
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;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x,c;
cin>>x>>c;
add.push_back({x,c});
alls.push_back(x);
}
for(int i=1;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 k=find(item.first);
a[k]+=item.second;
}
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);
cout<<s[r]-s[l-1]<<endl;
}
return 0;
}