離散化(整數保序離散化)(標準版)
對於值域比較大(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;
}