离散化

离散化:有序:原先x<y,那么f(x)<f(y)
用于范围比较大,例如[0,1e9],有的时候需要这些下标的数组来进行操作,例如并查集,但是不能开这么大,同时每次只有1e5个数,所以便可以进行离散化,将给出的1e5个数映射到[1,1e5+1]上去
但是存在几个小难题;
1:给出的数中存在重复元素
2:如何算出给出的数映射(离散化)之后的数

解决重复元素的问题

vector<int>all;//存储所有待离散化的值 
sort(all.begin(),all.end());//将a数组排序 
all.erase(unique(all.begin(),all.end()),all.end());//去掉重复元素

解决计算映射的问题

int find(int x){//找到第一个大于等于x的值,如果是配合离散化使用的话,找到的就是等于x的值 
  int l=0,r=all.size()-1;
  while(l<r){
    int mid=(l+r)>>1;
    if(all[mid]>=x) r=mid;
    else l=mid+1;
  }
  return r+1;//映射的是1 2 3...n 若是返回r,映射的是0 1 2 ...n-1 
}

 

lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

所以find函数可以直接调用lower_bound()函数

int find(int y)
{
    return lower_bound(all.begin(), all.end(), y) - ys.begin()+1;//+1表示下标从1开始
}

 

写于:2020/8/23 12:45

修改于:202/8/28 22:55

posted @ 2020-08-23 12:46  白菜茄子  阅读(101)  评论(0)    收藏  举报