用归并排序
参考博客归并排序的实现与求逆序对数
ll MergeSort(int s[], int left, int middle, int right)
{
int i = left, j = middle;
int b[right - left + 1];
int index = 0;
ll sum = 0;
int t = 0;
while (i < middle && j <= right)
{
if (s[i] > s[j])
{
b[index++] = s[j++];
t++;
}
if (s[i] <= s[j] || j == right + 1)
{
sum +=(ll) t * (middle - i);
b[index++] = s[i++];
t = 0;
}
}
while (i < middle)
b[index++] = s[i++];
while (j <= right)
b[index++] = s[j++];
index = 0;
for (int m = left; m <= right; m++)
s[m] = b[index++];
return sum ;
}
ll k = 0;
void Merge(int s[], int low, int high)
{
if (low < high)
{
int mid = (low + high) / 2;
Merge(s, low, mid);
Merge(s, mid + 1, high);
k += MergeSort(s, low, mid + 1, high);
}
}
用树状数组
参考博客树状数组(求逆序对)
int a[maxn],tree[4*maxn];
void update(int x) {
for(; x<=n; x+=-x&x)
tree[x]++;
}
int sum(int x) {
int acc=0;
for(; x; x-=x&-x)
acc+=tree[x];
return acc;
}
for(int i=1; i<=n; i++) {
ans+=i-1-sum(a[i]);
update(a[i]);
}
return ans;