離散化1(算法)

離散化(整數保序離散化)(標準版)

對於值域比較大(0-10^9),對於這些值,我們需要把他們當成下標來做,我們可以把它映射到從1開始連續的數組之中存儲

假設:a[] = {1,3,100,2000,5000000}//a有序

映射之後 1->0 3->1 100->2 2000->3 5000000->4

問題:

  1. a[]中可能存在重複元素 所以需要去重

    vector<int>a;//存儲所有待離散化的值
    sort(a.begin(),a.end());//排序
    a.erase(unique(a.begin(),a.end()),a.end());//去重
    
  2. 如何算出某個數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;
} 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章