POJ2299 Ultra-sort可以转成求逆序数。
如果规模比较小,求逆序数可以用冒泡的方法做,简单。还可以用归并排序做,先分别求左右两部分的逆序数,两部分都排好序后再求两者之间的逆序数。因此求逆序数是归并排序的副产品。与归并排序的主要差别也就在一句ret += (a + m - posa);
没有ac,惭愧。
#include <cstdio>
#include <vector>
using namespace std;
__int64 mergearr(int* a, int m, int* b, int n)
{
__int64 ret = 0;
int* assit = new int[m + n];
int* posa = a, *posb = b, *cur = assit;
while (posa < a + m && posb < b + n)
{
if (*posa <= *posb)
{
*cur = *posa;
++cur;
++posa;
}
else
{
*cur = *posb;
++cur;
++posb;
ret += (a + m - posa);
}
}
if (posa == a + m)
{
for (; posb < b + n; ++posb,++cur)
{
*cur = *posb;
}
}
else
{
for (; posa < a + m; ++posa, ++cur)
{
*cur = *posa;
}
}
memcpy(a, assit, sizeof(int) * (m + n));
delete assit;
return ret;
}
__int64 mergesort(int* base, int n)
{
if (n == 1)
{
return 0;
}
int half = (n >> 1);
__int64 ret = mergesort(base, half);
ret += mergesort(base + half, n - half);
ret += mergearr(base, half, base + half, n - half);
}
int main()
{
int i,n;
vector<int> vec;
vec.resize(500001);
for (; ;)
{
scanf("%d", &n);
if (!n)
{
break;
}
for (i = 0; i < n; ++i)
{
scanf("%d", &vec[i]);
}
__int64 res = mergesort(&vec[0], n);
printf("%I64d/n", res);
}
return 0;
}