2019.12.21日常总结兼离散化略讲

离散化


Part one:基本概念

离散化,大家可以简单的理解为把大的内容通过某种方式压缩成小的内容。在OI竞赛中,离散化通常是在主算法已经写好的情况下,作为辅助工具进行的。

离散化有很多种,今天讲最简单的一种:整数离散化(当然,这名字是编者起的,并非专业)。


Part two:整数离散化

所谓整数离散化,就是将一组大的数字进行重新编号,使得其范围大大减小。同时,重新编号不能破坏原有数字的大小关系,而且,为了方便处理,我们通常给它们编号为整数。

举个例子:比如原数字为 [ 1 × 1 0 10 , 234234 , 45346 , 234234 ] [1 \times 10^{10},234234,-45346,234234] ,我们可以把它们重新编号为 [ 3 , 2 , 1 , 2 ] [3,2,1,2] ,在它们的大小关系没有被破坏的前提下,我们将它们的范围大大缩小。

当然,因为我们把原数字修改了,所以离散化之后,有些问题便无法求解(如判断是否有原数字等于给定数字)。


Part three:如何整数离散化

我们把原数组排序,然后从小到大一一编号即可,最后按照原顺序重新排回来。

【代码】:

struct node{
	int id,number,num;
}a[N];int n;
inline bool cmp1(node a,node b){
	return a.number<b.number;
}
inline bool cmp2(node a,node b){
	return a.id<b.id;
}
inline void discretization(){
//	离散化原数组
	sort(a+1,a+n+1,cmp1);
	a[0].number=a[1].number-1;
	for(int i=1;i<=n;i++)
		if (a[i].number>a[i-1].number)
			a[i].num=a[i-1].num+1;
		else a[i].num=a[i-1].num;
	sort(a+1,a+n+1,cmp2);
}

顺带一提:离散化后,所有数字的范围最最多是 1 n 1-n n n 为数字个数)。


Part four:离散化的应用

【收集雪花】:
不同的雪花往往有不同的形状。在北方的同学想将雪花收集起来,作为礼物送给在南方的同学们。一共有 n n 个时刻,给出每个时刻下落雪花的形状,用不同的整数表示不同的形状。在收集的过程中,同学们不希望有重复的雪花。你可以从任意 a a 时刻开始,在 b b 时刻停止。 a a b b 时刻中间的雪花也都将被收集。他们希望收集的雪花最多。
【思路】: 如果 a , b a,b 范围小,完全可以用尺取法搞定。 a , b a,b 范围大,但是只有它们的大小关系对于我们是有用的,所以我们可以离散化
【代码】:

const int N=1e6+100;
struct node{
	int id,number,num;
}a[N];int n,ans;bool b[N];
inline bool cmp1(node a,node b){
	return a.number<b.number;
}
inline bool cmp2(node a,node b){
	return a.id<b.id;
}
inline void discretization(){
//	离散化原数组
	sort(a+1,a+n+1,cmp1);
	a[0].number=a[1].number-1;
	for(int i=1;i<=n;i++)
		if (a[i].number>a[i-1].number)
			a[i].num=a[i-1].num+1;
		else a[i].num=a[i-1].num;
	sort(a+1,a+n+1,cmp2);
}
inline void Determining(){
	memset(b,false,sizeof(b));
	for(int l=1,r=1;l<=n;l++){
		b[a[l-1].num]=false;
		while (r<=n&&!b[a[r].num]){
			b[a[r].num]=true;r++;
		}
		ans=max(ans,r-l);
	}
}
#define gc getchar()
#define g(c) isdigit(c)
inline int read(){
	char c=0;int x=0;bool f=0;
	while (!g(c)) f=c=='-',c=gc;
	while (g(c)) x=x*10+c-48,c=gc;
	return f?-x:x;
}
inline int hpwwzyy2012(){
	n=read();
	for(int i=1;i<=n;i++){
		a[i].id=i;
		a[i].number=read();
	}
	discretization();
	Determining();
	printf("%d",ans);
	return 0;
}
int main(){
//	freopen("t1.in","r",stdin);
	return hpwwzyy2012();
}
发布了82 篇原创文章 · 获赞 4 · 访问量 1774

猜你喜欢

转载自blog.csdn.net/ZHUYINGYE_123456/article/details/103643426