POJ 2299 Ultra-QuickSort

来源:互联网 发布:jersey 返回json 编辑:程序博客网 时间:2024/05/12 16:11

POJ 2299 Ultra-QuickSort

思路:怎么说呢~这题比较简单,很容易就看出来是求逆序数了,用树状数组就行,树状数组的第一种用法~但是这里有个问题就是0<=a[i]<=999999999,这个数据范围要开那么长的数组肯定不行~不过好在n<500000,就是说正常来讲数组最大也就开500000长度而已~~~

这个好办,只要把元素都映射进去就好了~~比如样例给的数据是9 1 0 5 4,映射之后的结果应该是5 2 1 4 3,映射成这样后就可以按正常的求逆序数做了~可以用map映射,也可以直接开个对象数组~~~

最后一点巨坑。。。让我wa了好几次。。。最后的结果应该是long类型的。。。wa了很多次找不到原因,试了试极端数据,唔~超过int型最大值了500000*499999/2>INT_MAX~~

话说~感觉很像冒泡排序额~这个题的意思就是求冒泡排序的元素的交换次数( ⊙o⊙ )随意一说,没什么意义。

这里就是用到树状数组统计的特点upDate(x,1),意思就是进来了一个值为x的元素,sum(x)意思是统计一下所有小于x的数的个数(相当于顺序数)

AC代码:

import java.util.Arrays;import java.util.Comparator;import java.util.Scanner;class Discrete{int a,p;}//a是元素的值,p是元素进来的顺序public class Main{static Scanner scan=new Scanner(System.in);private static int lowbit(int x) {return x&(-x);}private static void upDate(int[] c,int n,int x,int add){for(int i=x;i<=n;i+=lowbit(i))c[i]+=add;}private static int sum(int[] c,int x){int sum=0;for(int i=x;i>0;i-=lowbit(i))sum+=c[i];return sum;}public static void main(String[] args){while(scan.hasNext()){int n=scan.nextInt();if(n==0) break;Discrete ap[]=new Discrete[n+1];for(int i=1;i<=n;i++){ap[i]=new Discrete();ap[i].a=scan.nextInt();ap[i].p=i;}Arrays.sort(ap,1,n+1,new Comparator<Discrete>() {@Overridepublic int compare(Discrete a, Discrete b){return (a.a>=b.a)?1:-1;//按值从小到大排序}});int a[]=new int[n+1];for(int i=1;i<=n;i++)//这里可写成a[i]=ap[i].p,映射出来的结果虽然不一样,但是直接对这个求逆序数结果一样正确,即对a[i].p求逆序数a[ap[i].p]=i;//对于样例9 1 0 5 4,注释中的映射方式即是对3 2 5 4 1求逆序数(这串数字是0 1 4 5 9)读入的顺序//按元素们进来时的位置,从小到大重新赋值成1~nint c[]=new int[n+1];long sum=0;for(int i=1;i<=n;i++){sum+=i-1-sum(c,a[i]);upDate(c,n,a[i],1);}System.out.println(sum);}}}

0 0
原创粉丝点击