离散化:
适用问题对象:数值范围大,但数据个数小的数据处理
操作步骤:离散化(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; }