1. 程式人生 > >POJ——2299(Ultra-QuickSort)樹狀陣列求逆序數

POJ——2299(Ultra-QuickSort)樹狀陣列求逆序數

In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 

9 1 0 5 4                                                        ,


Ultra-QuickSort produces the output 

0 1 4 5 9 .


Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input

The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

Output

For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0

題意:給出一串數,求出使用快排變成從小到大排序的最小交換次數。

題解:根據快排加找規律,可以看出就是求這一串數的逆序數,然後就用樹狀陣列寫了。因為資料規模大,需要離散化一下,就是去重,重複的數用相同的數表示,所以需要排序。具體看程式碼。

import java.util.*;
public class Main {
	static Scanner cin = new Scanner(System.in);
	static int n;
	static int [] a;
	static int [] c;
	static int lowbit(int x) {
		return x&(-x);
	}
	static class Node implements Comparable<Node>{
		int val;
		int index;
		public int compareTo(Node w) {
			return this.val-w.val;
		}
	}//離散化,因為資料大
	static int query(int x) { //1-x求和
		int sum=0;
		while(x!=0) {
			sum+=a[x];
			x-=lowbit(x);
		}
		return sum;
	}
	static void add(int x,int v) {
		while(x<=n) {
			a[x]+=v;
			x+=lowbit(x);
		}
	}
	public static void main(String[] args){
		while(cin.hasNext()) {
			long sum=0;
			n = cin.nextInt();
			Node[] node=new Node[n];
			if(n==0) break;
			a = new int [n+5];
			c = new int [n+5];
			for (int i = 0; i < n;i++) {
				node[i] = new Node();
				node[i].val=cin.nextInt();
				node[i].index=i+1;
			}
			Arrays.sort(node);//排序
			int id=1;
			//Arrays.fill(c,0);
			c[node[0].index]=id;	
			for(int i = 1;i < n;i++){//離散化
				if(node[i].val!=node[i-1].val)
					c[node[i].index]=++id;
				else
					c[node[i].index]=id;
			}
			for(int i = 1;i <= n;i++){
				add(c[i],1);//單點更新
				sum+=i-query(c[i]);//求 逆序數
			}
			System.out.println(sum);
		}
	}
}