求逆序数,实际上有多种方法,枚举法,插入排序法,冒泡排序算法,归并排序算法,树状数组等方法都可以求解逆序数,前三种当数据比较多时效率比较低,由于数据比较大因此利用树状数组求解时可以把原来数组离散化!
离散化:
9999999 66666666 5555 777777 ··············(1)
1 2 3 4 ··············(2)
序列(2)是序列(1)的下表;当对(1)排序后可知序列(2)的排列状态为(2‘): 3 4 1 2 ,因此求原序列(1)的逆序数,就是求序列(2’)的逆序数,处理起来比较方便!
一下有两种求解方法,第一个代码是归并排序算法求解,另一个为树状数组求解,仅供参考!
//归并排序来求解逆序数,记得不能全部初始化,否则会超时!
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int MAXN = 500000;
int a[MAXN], b[MAXN];
LL sum ;
void Merge(int low, int mid, int high)
{
//memset(b, 0, sizeof(b));
int i = low, j = mid+1, k = low;
while(i <= mid && j <= high)
{
if(a[i] <= a[j])
b[k++] = a[i++];
else
b[k++] = a[j++], sum += (mid - i+1);
}
while(i <= mid)
b[k++] = a[i++];
while(j <= high)
b[k++] = a[j++];
for(i = low; i <= high; ++i)
a[i] = b[i];
return ;
}
void Merge_Sort(int low, int high)
{
if(low == high)
return ;
if(low < high)
{
int mid = (low + high) >> 1;
Merge_Sort(low, mid);
Merge_Sort(mid+1, high);
Merge(low, mid, high);
}
}
int main()
{
int n, i;
while(~scanf("%d", &n) && n)
{
//memset(a, 0, sizeof(a));
for(i = 0; i < n; ++i)
scanf("%d", &a[i]);
sum = 0;
Merge_Sort(0, n-1);
printf("%I64d\n", sum);
}
return 0;
}
树状数组:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 500000;
typedef long long LL;
int a[MAXN], c[MAXN];
struct Node
{
int index;
int num;
Node()
{
index = 0;
num = 0;
}
}Tree_arr[MAXN];
/**
int cmp(const void* a, const void* b)
{
Node* aa = (Node *)a;
Node* bb = (Node *)b;
return aa->num - bb->num;
}*/
bool cmp(Node a, Node b)
{
return a.num < b.num;
}
int LowBit(int x)
{
return x & (-x);
}
void UFset(int n, int pos, int num)
{
while(pos <= n)
{
c[pos] += num;
pos += LowBit( pos );
}
}
int Query(int pos, int sum)
{
while(pos > 0)
{
sum += c[pos];
pos -= LowBit( pos );
}
return sum;
}
int main()
{
int n;
LL sum;
while(~scanf("%d", &n) && n)
{
for(int i = 1; i <= n; ++i)
{
scanf("%d", &Tree_arr[i].num);
Tree_arr[i].index = i;
}
//qsort(Tree_arr+1, n, sizeof(Tree_arr[0]), cmp);
sort(Tree_arr+1,Tree_arr+n+1, cmp);
for(int i = 1; i <= n; ++i)
a[Tree_arr[i].index] = i;
memset(c, 0, sizeof(c));
sum = 0;
for(int i = 1; i <= n; ++i)
{
UFset(n, a[i], 1);
sum += a[i] - Query(a[i], 0);
}
printf("%I64d\n", sum);
}
return 0;
}