离散化
Posted ppxppx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了离散化相关的知识,希望对你有一定的参考价值。
最近碰到好多题都先要离散化处理一下,本蒟蒻全挂了~~
离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。例如:
原数据:1,999,100000,15;
处理后:1,3,4,2;
原数据:{100,200},{20,50000},{1,400};
处理后:{3,4},{2,6},{1,5};
————《百度百科》
首先真的不要被离散化这个名字吓到了,离散化就是一种简单的思想,而且它是有模板的;
我们一般什么时候会用到离散化呢?就是当题目的数据范围很大,我们不可能开那么大的数组(什么一亿十亿的)来存这些数据,但是这些数据元素的个数却不多(在我们能够接受的合理范围内),这时我们就可以对这些超级大的数据进行离散化了;
就像上述百度百科举的两个例子那样,对的!离散化的思想就是这么简单;
但不得不提一下,对数据进行离散化,一定要考虑的是我们只想知道这些数据之间的相对大小,而不太在意它们的绝对大小,怎么理解这句话呢?用百度百科的第一个例子:
1,999,100000,15;
这四个数据离散化后:
1,3,4,2
我们不难发现离散化后我们只能知道数据之间的相对大小,但无法确定它们的真实值;
离散化的三个步骤:
1 sort排序
2 unique去重
3 lower_bound索引
不得不感叹STL大法
模板:
int n;
for(int i=1; i<=n; i++){
scanf("%d",&a[i]);
b[i]=a[i]; //b[]是a[]的副本
}
sort(b+1,b+n+1); //排序
int sum=unique(b+1,b+1+n)-b-1; //去重
for(int i=1; i<=n; i++)
a[i]=lower_bound(b+1,b+1+sum,a[i])-b;//索引
例:洛谷P4168 蒲公英
题目描述
在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。
为了简化起见,我们把所有的蒲公英看成一个长度为n的序列 (a_1,a_2..a_n)(a1,a2..an),其中ai为一个正整数,表示第i棵蒲公英的种类编号。
而每次询问一个区间 [l,r],你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。
注意,你的算法必须是在线的;
输入输出格式
输入格式:
第一行两个整数n,m ,表示有n株蒲公英,m次询问。
接下来一行n个空格分隔的整数(a_i),表示蒲公英的种类
再接下来m行每行两个整数(l_0,r_0);
我们令上次询问的结果为x(如果这是第一次询问,则x=0)。
令l=((l_0)+x?1)mod n+1,r=((r_0)+x?1)mod n+1,如果(l>r)交换l,r;最终的询问区间为([l,r]);
输出格式:
输出m行。每行一个整数,表示每次询问的结果。
#pragma GCC optimize(3)
//因为枚举暴力,所以手动O3,不然过不了
#include<bits/stdc++.h>
using namespace std;
int a[50001],b[50001],t[50001];
//a[]索引的值,b[]排序去重,t[]枚举暴力的桶子
int main(){
int n,m,ll,rr,l,r,x=0;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
int sum=unique(b+1,b+1+n)-b-1;
for(int i=1; i<=n; i++)
a[i]=lower_bound(b+1,b+1+sum,a[i])-b;
//离散化模板
for(int i=1;i<=m;i++){ //枚举
memset(t,0,sizeof(t));
scanf("%d%d",&ll,&rr);
l=(ll+x-1)%n+1;
r=(rr+x-1)%n+1;
if(l>r) swap(l,r);
for(int j=l;j<=r;j++){
t[a[j]]++;
}
int max=0,place=0;
for(int j=1;j<=sum;j++)
if(t[j]>max){
max=t[j];
place=j;
}
printf("%d
",b[place]);
x=b[place];
}
return 0;
}
离散化一般都只是作为辅助,在正式的算法开始之前对数据进行预处理的操作;
以上是关于离散化的主要内容,如果未能解决你的问题,请参考以下文章