802. 区间和
离散化是一种解题思路 , 即把比较大的区间范围内出现过的数(这些数大小相差比较大或者出现的数比较少)映射成小区间范围内的数,说白了就是把离散的一些数集中起来,但维持原来的相对顺序以便进行区间类的处理. (详情看代码注释吧.
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
vector<PII> add , query;
vector<int> alls; // 储存大区间内所有出现过的数
int a[300010] , s[300010];
int find(int x){
int pos;
pos = lower_bound(alls.begin(),alls.end(),x) - alls.begin() ; //查询集中起来后的数的下标
return pos+1; //下标从 1 开始;
}
int main()
{
int n,m,x,c;
cin>>n>>m;
while(n--){
cin>>x>>c;
add.push_back({x,c});
alls.push_back(x);
}
while(m--){
cin>>x>>c;
query.push_back({x,c});
alls.push_back(x);
alls.push_back(c);
}
sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(), alls.end()) , alls.end()); //在大区间内出现过的数集中排序去重
// unique()把不重复的元素排序放在最前边, 返回这些有序序列最后一个元素的后一个迭代器;
for(auto item : add){
int pos = find(item.first); //查询下标 ,然后累加;
a[pos] += 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);
int r = find(item.second);
cout<<s[r]-s[l-1]<<endl;
}
return 0;
}