离散化:
适用问题对象:数值范围大,但数据个数小的数据处理
操作步骤:离散化(sort)——去重(erase+unique)——找到离散化后的位置
函数这是:
erase(begin,end):删除begin到end
unique(begin,end):去除begin到end的重复数字放在容器最前面,返回去重后的最后地址
#include <bits/stdc++.h>
using namespace std;
int n,m,x,c,l,r;
typedef pair<int,int> P;//第一个值为加数的位置,第二个为加的数值
vector<int> alls;//记录加数位置,询问区间左、右位置
vector<P> add,query;//add为加数位置及数值,query记录询问左,右区间
const int N=300005;
int a[N],s[N];//a为离散化后加数序列原数组,s为a的前缀和序列
int main(int argc, char** argv) {
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%d%d",&x,&c);
add.push_back({x,c});
alls.push_back(x);
}
for(int i=1;i<=m;i++){
scanf("%d%d",&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 it:add){//构建离散化后加数的原数组序列
int x=lower_bound(alls.begin(),alls.end(),it.first)-alls.begin()+1;//前缀和要留下a[0],因为s[0]要==0所以所有位置往后移1格
a[x]+=it.second;//可能出现一个位置加多次
}
for(int i=1;i<=alls.size();i++) s[i]=s[i-1]+a[i];//构建前缀和序列
for(auto it:query){
l=lower_bound(alls.begin(),alls.end(),it.first)-alls.begin()+1,
r=lower_bound(alls.begin(),alls.end(),it.second)-alls.begin()+1;
cout<<s[r]-s[l-1]<<endl;//前缀和区间求和
}
return 0;
} 
京公网安备 11010502036488号