可进行点和线段的离散化
template<class T>
struct line
{
T a,b;
};
template<class T>
struct helper
{
T v;//原值
int index;//原值的位置
static int cmp(const void*a,const void*b)
{
T r=((helper<T>*)a)->v-((helper<T>*)b)->v;
if(r==0)
return ((helper<T>*)a)->index-((helper<T>*)b)->index;
return r;
}
};
template<class T>
struct lisan
{
helper<T>* h;//h[i]表示离散化后的有序数组的第i项
int* anti;//anti[i]表示离散化后的i值在h中的位置
int* get(T* v,int n)//将v数组离散化成int数组并返回,将映射关系储存在h和anti中
{
h=new helper<T>[n];
anti=new int[n];
fill(anti,anti+n,-1);
for(int i=0;i<n;i++)
h[i].v=v[i],h[i].index=i;
qsort(h,n,sizeof(helper<T>),helper<T>::cmp);
int* res=new int[n];
for(int i=0,j=0;i<n;i++){
if(i!=0&&h[i].v!=h[i-1].v)j++;
res[h[i].index]=j;
if(anti[j]==-1)anti[j]=i;
}
return res;
}
int res(int v)//求出离散化后的v值在原数组中第一次出现的位置
{
return h[anti[v]].index;
}
int range;//离散化后的线段右端的最大值
line<int>* get(line<T>* v,int n)//将线段数组离散化成整形线段数组并返回,将映射关系储存在h和anti中
{
h=new helper<T>[n+n];
anti=new int[n+n];
fill(anti,anti+n+n,-1);
for(int i=0;i<n;i++)
{
h[i+i].v=v[i].a;h[i+i].index=i+i;
h[i+i+1].v=v[i].b;h[i+i+1].index=i+i+1;
}
qsort(h,n+n,sizeof(helper<T>),helper<T>::cmp);
line<int>* res=new line<int>[n];
int j=0;
for(int i=0;i<n+n;i++)
{
if(i!=0&&h[i].v!=h[i-1].v)j++;
if(h[i].index%2==0)res[h[i].index/2].a=j;//h[i].index%2==0表示h[i].v是第h[i].index/2条线段的左侧
else
res[h[i].index/2].b=j;
if(anti[j]==-1)anti[j]=i;
}
range=j;
return res;
}
};