归并排序模板题
相关文章
//采用归并排序,归并的过程可以算出逆序对的个数//所有的逆序对个数 = /*排序后,两个数都在左边的逆序对数排序后,两个数都在右边的逆序对数如果一个数在左边,一个数在右边,在归并的过程中*/
//左边 <= 右边,正常归并。如果左边 > 右边
//那么左边往右的所有数都可以和右边的第一个数构成逆序对
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class Main{static int n;static final int N = 100010;static int[] a = new int[N];static int[] t = new int[N];static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));public static void main(String[] args)throws IOException {n = Integer.parseInt(in.readLine());String[] data = in.readLine().split(" ");//读取数据for (int i = 0; i < n; i++) a[i] = Integer.parseInt(data[i]);//调用归并排序得到结果long res = merge_sort(a,0,n - 1);System.out.println(res);in.close();}public static long merge_sort(int a[],int l,int r){//分治结束条件if (l >= r) return 0;long res = 0;int mid = l + r >> 1;res = merge_sort(a,l,mid) + merge_sort(a,mid + 1,r);//归并算最终结果,当a[i] > a[j] 时要特殊处理int k = 0,i = l,j = mid + 1;while (i <= mid && j <= r){if (a[i] <= a[j]) t[k++] = a[i++];else {t[k++] = a[j++];//相当于计算[i,mid]之间有多少个数res += mid - i + 1;}}//剩余的数直接放入即可while (i <= mid) t[k++] = a[i++];while (j <= r) t[k++] = a[j++];//最后将排序的数还给a[]for(i = l,j = 0;i <= r;i++,j++) a[i] = t[j];return res;}
}