离散化
把大范围映射为小范围
像这题,下标$ 10^9 $太大,需要缩小范围
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
const int N = 300000; // 为什么开300000? (add的时候x,查询的时候l,r)
int n,m;
int a[N],s[N];
vector<int> alls;
vector<PII> add,query;
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; // 为什么返回r + 1,这是变相的让映射后的数组从1开始。
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
int x,c;
scanf("%d%d",&x,&c);
alls.push_back(x); // 把10^9 的大数都push进alls中进行离散化
add.push_back({x,c}); // 把操作先存下来
}
for(int i=0;i<m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
alls.push_back(l); // 把10^9 的大数都push进alls中进行离散化
alls.push_back(r); // 把10^9 的大数都push进alls中进行离散化
query.push_back({l,r}); // 把操作先存下来
}
sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(), alls.end()), alls.end()); // 去重,一定要在排序后进行
for(auto item:add)
{
int x=find(item.first);
a[x]+=item.second;
}
for(int i=1;i<=alls.size();i++) s[i]=s[i-1]+a[i]; // 前缀和,下标从1开始,所以find()返回+1
for(auto item:query)
{
int l=find(item.first),r=find(item.second); // 二分查找离散化后的下标
cout<<s[r]-s[l-1]<<endl;
}
return 0;
}