适用:值域跨度很大,但所用的很稀疏
//一个无限长坐标轴 在某个位置加上一个数(n次) 询问从l到r之间共加了多少(询问m次)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=3e5+10;
int a[N],s[N],n,m;
vector<int> cun; //cun 存所有加上数的坐标 以及 需要查询的坐标
typedef pair<int,int> PII; //pair比较方便 (x处,加上s)(查询l,查询r)都是两两一对
vector<PII> add,zhao; //add存所有加数的坐标以及加的数 zhao存所有要查询的坐标
int find(int x) //死模板,二分查找(离散化必备)
{
int l=0,r=cun.size()-1;
while(l<r)
{
int mid=l+r>>1;
if(cun[mid]>=x)
r=mid;
else
l=mid+1;
}
return r+1; //因为映射到a数组中是从1开始 所以现在要加1(cun里是从0开始存的)
}
int main(void)
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
int xi,x;
cin>>xi>>x;
add.push_back({xi,x}); //存进add中
cun.push_back(xi); //坐标存进cun中
}
for(int i=0;i<m;i++)
{
int l,r;
cin>>l>>r;
zhao.push_back({l,r}); //存进zhao中
cun.push_back(l); //坐标都存进cun中
cun.push_back(r);
}
//去重
sort(cun.begin(),cun.end()); //先排序
cun.erase(unique(cun.begin(),cun.end()),cun.end()); //背过
for(auto i:add)
{
int x=find(i.first); //找出add里第一个元素,就是加数的坐标排第几个
a[x]+=i.second; //在第x个位置加上add里第二个元素,也就是要加的数
}
for(int i=1;i<=cun.size();i++)
s[i]=s[i-1]+a[i]; //前缀和
for(auto i:zhao)
{
int l=find(i.first);
int r=find(i.second);
cout<<s[r]-s[l-1]<<endl;
}
return 0;
}0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复