5. 逆序对数
问题:
给一列数<a1,a2,......,an>,求它的逆序对,即有多少个有序对(i.j),使得i<j且ai<aj; n 可以高达106
可以采用归并排序的思路
首先将原问题可以分解为两个子问题:对原序列从中间一分为二,分解为两个子序列A,B
两个子问题可以分别递归求解,求得的逆序数分别是na和nb
合并:如果两个子序列A,B分别有序,那么可以在归并过程中求出数对(ai,bj){ai在A中,bj在B中}的逆序数,具体过程如下:
如果ai<bj,则两者没有发生逆序,直接执行归并即可
如果 ai>bj,则发生逆序,ai以及后面的元素都和bj构成逆序
那么这个过程中求得的逆序数和na,nb的和就是原问题的解
#include<iostream> using namespace std; int n; int *a; int fun(int l, int mid, int r) { int cnt = 0; for (int i = l; i <= mid; i++) for (int j = mid + 1; j <= r; j++) if (a[i] < a[j]) cnt++; return cnt; } int solve(int l, int r) { if (l == r) return 0; int mid = (l + r) / 2; return solve(l, mid) + solve(mid+1, r) + fun(l, mid, r); } int main() { scanf("%d", &n); a = new int[n]; for (int i = 0; i < n; i++) scanf("%d", &a[i]); cout << solve(0, n-1) << endl; delete[] a; return 0; }
人生不如意的时候,是上帝给的长假,这个时候应该好好享受假期。
突然有一天假期结束,时来运转,人生才是真正开始了。
突然有一天假期结束,时来运转,人生才是真正开始了。