n 个魔法学徒站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个学徒。
每个学徒都有一个不高兴的程度。初始时所有学徒的不高兴程度都是0。
如果某个学徒第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个学徒第k次交换时,他的不高兴程度增加k。
试求让所有学徒按从低到高排队,他们的不高兴程度之和最小是多少。
如果有两个学徒身高一样,则他们谁站在谁前面是没有关系的。
【输入格式】
输入的第一行包含一个整数n,表示学徒的个数。
第二行包含 n 个整数 H1,H2,… ,Hn,分别表示每个学徒的身高。
【输出格式】
输出一行,包含一个整数,表示学徒的不高兴程度和的最小值。
【输入样例】
3
3 2 1
【输出样例】
9
【样例说明】
首先交换身高为3和2的学徒,再交换身高为3和1的学徒,再交换身高为2和1的学徒,每个学徒的不高兴程度都是3,总和为9。
【数据规模】
对于100%的数据,1≤n≤100 000,0≤Hi≤1 000 000。
//java code
import java.util.*;
public class Main {
static class Child {
int high;//身高
int count;//交换次数
public Child(int high) {
this.high = high;
this.count = 0;
}
}
static void sort(Child c[]) {
if (c.length > 1) {
Child leftc[] = getHalf(c, 0);
Child rightc[] = getHalf(c, 1);
sort(leftc);
sort(rightc);
merge(c, leftc, rightc);
}
}
static Child[] getHalf(Child c[], int tag) {
int len = c.length;
Child half[];
if (tag == 0) {
half = new Child[len / 2];
for (int i = 0; i < half.length; i++) {
half[i] = c[i];
}
} else {
half = new Child[len-len / 2];
for (int i = 0; i < half.length; i++) {
half[i] = c[len / 2 + i];
}
}
return half;
}
static void merge(Child c[], Child leftc[], Child rightc[]) {
int i = 0, j = 0;
int lenL = leftc.length, lenR = rightc.length;
while (i < lenL && j < lenR) {//计算左半边中大于rightc[j]的数量
if (leftc[i].high > rightc[j].high) {
rightc[j].count += (lenL - i);
j++;
} else i++;
}
i = lenL - 1;
j = lenR - 1;
while (i >= 0 && j >= 0) {//计算右半边中小于leftc[i]的数量
if (leftc[i].high > rightc[j].high) {
leftc[i].count += (j + 1);
i--;
} else j--;
}
//归并排序
i = 0;
j = 0;
int t = 0;
while (i < lenL && j < lenR) {
if (leftc[i].high < rightc[j].high)
c[t++] = leftc[i++];
else
c[t++] = rightc[j++];
}
while (i < lenL)
c[t++] = leftc[i++];
while (j < lenR)
c[t++] = rightc[j++];
}
public static void main(String[] args) {
Main ss=new Main();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Child child[] = new Child[n];
for (int i = 0; i < n; i++) {
int high = sc.nextInt();
child[i] = new Child(high);
}
ss.sort(child);
long ans=0;
for (int i = 0; i < n; i++) {
long count = child[i].count;
ans += count * (count + 1) / 2;
}
System.out.println(ans);
}
}