acwing.区间和(离散化)

对数据范围较大,但有用的数据较少的题目使用。

中心思想:把所有用到的元素的位置按照一定的顺序映射到一个从0或1为起点的数组中,并把所有用到的元素的值存储在映射数组中,可以利用二分查找确定某个元素映射的位置。

#include<bits/stdc++.h>
using namespace std;

int arr[300010],pre_sum[300010];//真实有用的坐标最多只有n+2*m个,(n次修改会用n个位置,m次询问会用2*m个位置)
vector<pair<int,int>> add,add2;
vector<int> xiab;

int f(int x){
	vector<int>::iterator i=lower_bound(xiab.begin(),xiab.end(),x);
	return i-xiab.begin();
}

int main(){
	int n,m;
	cin>>n>>m;
	//先把所有用到的下标放到数组中
	for(int i=1;i<=n;i++){
		int x,c;
		cin>>x>>c;
		add.push_back({x,c});
		xiab.push_back(x);
	}
	for(int i=1;i<=m;i++){
		int l,r;
		cin>>l>>r;
		add2.push_back({l,r});
		xiab.push_back(l);
		xiab.push_back(r);
	}
	//排序所有用到的下标,然后去重。
	sort(xiab.begin(),xiab.end());//排序去重,为什么不用set,因为set类型的迭代器只能进行++或--操作,查询其中元素位置时不便。
	xiab.erase(unique(xiab.begin(),xiab.end()),xiab.end());//unique()去重,返回去重后最后一个元素的位置
	
	
	//开一个数组记录所映射位置的元素值,利用二分查找映射的位置,需要加值的进行处理。
	for(int i=1;i<=n;i++){
		int t=f(add[i-1].first)+1;
		arr[t]=arr[t]+add[i-1].second;
	}
	
	
	for(int i=1;i<=xiab.size();i++){
		pre_sum[i]=pre_sum[i-1]+arr[i];
	}
	for(int i=0;i<m;i++){
		int l=f(add2[i].first)+1;
		int r=f(add2[i].second)+1;
		cout<<pre_sum[r]-pre_sum[l-1]<<endl;
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值