离散化1(算法)
离散化(整数保序离散化)(标准版)
对于值域比较大(0-10^9),对于这些值,我们需要把他们当成下标来做,我们可以把它映射到从1开始连续的数组之中存储
假设:a[] = {1,3,100,2000,5000000}//a有序
映射之后 1->0 3->1 100->2 2000->3 5000000->4
问题:
-
a[]中可能存在重复元素 所以需要去重
vector<int>a;//存储所有待离散化的值 sort(a.begin(),a.end());//排序 a.erase(unique(a.begin(),a.end()),a.end());//去重
-
如何算出某个数x离散化后的值 二分
int find(int x){//找到第一个大于等于x的位置 int l=0,r = a.size()-1; while(l<r){ int mid = l+r>>1; if(a[mid]>=x)r=mid; else l = mid+1; } return r+1; }
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 3e5+10;
int n,m;
int a[N],s[N];
typedef pair<int,int>PII;
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;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
int x,c;
cin>>x>>c;//x为坐标,c为值
add.push_back({x,c});
alls.push_back(x);//坐标扔进来
}
for(int i=0;i<m;i++){
int l,r;
cin>>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());
//将c插入进坐标中
vector<PII>::iterator it = add.begin();
for(;it!=add.end();it++){
int x = find(it->first);
a[x]+=it->second;
}
for(int i=1;i<=alls.size();i++)s[i]=s[i-1]+a[i];
vector<PII>::iterator itt = query.begin();
for(;itt!=query.end();itt++){
int l = find(itt->first),r = find(itt->second);
cout<<s[r]-s[l-1]<<endl;
}
return 0;
}