离散化:当给出的一组数据的范围较大,而个数较少时,可以将这组数据离散化。例如,数组9,5,2,1,7离散化后变为5,3,2,1,4。以备例如开数组计算各值个数或建树状数组之需。
离散化方法之一——对存在重复数字的数组,使得相等的值在离散化后依然相等——步骤:
1.数组a存放原始数据n个
2.new一个SortedSet集合set,将a中元素add到set中。(set只可以存放不相同的数字,并将其从小到大排序)
3.将set中的元素按顺序存放到数组b中。
4.将a元素替换为b中相等元素的下标值+1,即可得到离散化数组a
注意:
1.注意b的大小为set的大小,而非a的大小n!!
2.对无法随机读取的集合类,java提供了一种方法即:
int ct=0;
for(int cur:set) {
b[ct++]=cur;
//System.out.println(b[ct-1]);
}
来方便地遍历并存入普通数组。
3.树状数组的下标必须从1开始,不能是0,lowbit对0没有办法。
4.因此,每一次对c[]清零时,都不要忘了让i<=n那个等号啊啊啊 debug半天。
5.关于lowerbound,之前的博客有讲。
以下是Poj2299 AC代码
public class test2 {
static int maxn=500010,n;
static long c[]=new long[maxn];
public static long lowbit(long x) {
return x&(-x);
}
public static void add(long x,int k) {
//System.out.println(x+" "+n);
while(x<=n) {
c[(int) x]+=k;
x+=lowbit(x);
}
}
public static int getsum(long x) {//求前x项和
int ans=0;
while(x>0) {
ans+=c[(int) x];
x-=lowbit(x);
}
return ans;
}
public static int lower_bound(long[] a,long x) {
int l=-1,r=b.length-1,mid=0;
while(r-l>1) {
mid=(l+r)/2;
if(a[mid]>=x) {
r=mid;
}else {
l=mid;
}
}
return r;
}
static long b[];
public static void main(String args[]) throws IOException {
long a[]=new long[maxn];
InputReader in=new InputReader(System.in);
SortedSet<Long> set=new TreeSet<Long>();
n=in.nextInt();
while(n!=0) {
long ans=0;
set.clear();
for(int i=0;i<=n;i++) {
c[i]=0;
}
//离散化,最终使a成为原a的离散化数组
for(int i=0;i<n;i++) {
a[i]=in.nextLong();
set.add(a[i]);
}
//将去重排序的set集合值赋给b
b=new long[set.size()];
int ct=0;
for(Long cur:set) {
b[ct++]=cur;
//System.out.println(b[ct-1]);
}
for(int i=0;i<n;i++) {
a[i]=1+lower_bound(b, a[i]);
//System.out.println(a[i]);
}
//树状数组
for(int i=0;i<n;i++) {
ans+=i-getsum(a[i]);
//System.out.println(a[i]+" "+getsum(a[i]));
add(a[i],1);
}
System.out.println(ans);
n=in.nextInt();
}
}
}
离散化方法之二:原数组重复元素离散化后不等——
class node{
int v, id;
}
public static void main(String args[]) {
int n,maxn;
node arr[]=new node[maxn];
for(int i=0;i<n;i++) {
arr[i].v=sc.nextInt();
arr[i].id=i;
}
Arrays.sort(arr,0,n);
int a[]=new int[maxn];
for(int i=1;i<=n;i++) {
a[arr[i].id]=i;
}
//得到a为arr离散化后数组
}
```