求逆序数,实际上有多种方法,枚举法,插入排序法,冒泡排序算法,归并排序算法,树状数组等方法都可以求解逆序数,前三种当数据比较多时效率比较低,由于数据比较大因此利用树状数组求解时可以把原来数组离散化!
离散化:
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; }