适用:值域跨度很大,但所用的很稀疏
//一个无限长坐标轴 在某个位置加上一个数(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分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论