离散化:有序:原先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