该题实际上就是求所给排列的逆序数个数。 因为最快的排序方法一定是先将最大的数放到最后,再将第二大的数放到最后...... 该贪心算法很容易证明。
方法有两种: 归并排序或者树状数组(线段树)。
下面用归并排序实现的:
细节参见代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1000000000;
const int maxn = 500000+5;
int n,m,a[maxn],b[maxn];
ll cnt = 0;
void merge_sort(int* A, int x, int y, int *T) {
if(y - x > 1) {
int m = x + (y-x)/2;
int p = x, q = m, i = x;
merge_sort(A, x, m, T);
merge_sort(A, m, y, T);
while(p < m || q < y) {
if(q >= y || (p < m && A[p] <= A[q])) T[i++] = A[p++];
else { T[i++] = A[q++]; cnt += m - p; }
}
for(i = x; i < y; i++) A[i] = T[i];
}
}
int main() {
while(~scanf("%d",&n)&&n) {
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
cnt = 0;
merge_sort(a,1,n+1,b);
printf("%lld\n",cnt);
}
return 0;
}