//acwing 802
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
vector<int> alls;
vector<PII> add, query;
const int N = 300010;
int a[N], s[N];
//实现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]) a[j ++ ] = a[i];
//执行完之后 a[0] ~ a[j - 1]都是有序不重复的数,返回指向a[j]的迭代器即可
return a.begin() + j;
}
//用整数二分算法,找到x在alls容器中对应的下标,作为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 l + 1; //返回 下标+1 作为离散值
}
int main()
{
int n, m;
cin >> n >> m;
//将x, l, r全部读入,保存在容器中,统一进行离散化
//x, l, r 离散化之后,相对位置不会发生改变
while (n -- )
{
int x, c;
cin >> x >> c;
add.push_back({x, c});
alls.push_back(x);
}
while (m -- )
{
int l, r;
cin >> l >> r;
query.push_back({l, r});
alls.push_back(l), alls.push_back(r);
}
//alls去重 --> 离散化时需将该数在alls中的下标作为离散值,不去重的话整数二分寻找某数下标时会出错
sort(alls.begin(), alls.end());
//alls.erase(unique(alls.begin(), alls.end()), alls.end()); //c++提供的unique()函数-->将相邻的重复元素全部搬至容器末尾
alls.erase(unique(alls), alls.end()); //自己实现的unique()函数
//处理在某个位置上插入值
for (auto item : add)
{
int x = find(item.first); //将x离散化,找到x在alls容器中对应的下标,作为x的离散值
a[x] += 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;
}
(C++) 基础算法学习:离散化
最新推荐文章于 2024-02-25 16:07:42 发布