787 归并排序基础
#include <iostream>using namespace std;const int N = 100010;int temp[N],a[N],n;void merge_sort(int a[], int l, int r){if(l >= r)return;int mid = (l + r) >> 1;merge_sort(a, l, mid);merge_sort(a, mid + 1, r);int k = 0, i = l, j = mid + 1;while (i <= mid && j <= r){if(a[i] < a[j]) temp[k++] = a[i++];else temp[k++] = a[j++];}while (i <= mid) temp[k++] = a[i++];while (j <= r) temp[k++] = a[j++];k = 0;for(int i = l; i<=r; i++ ) a[i]=temp[k++];}int main (){scanf("%d", &n);for(int i = 0; i < n; i ++ ) scanf("%d", &a[i]);merge_sort(a, 0, n-1);for(int i = 0; i < n; i++ )printf("%d ",a[i]);return 0;}
788 逆序对的数量

地址:https://www.acwing.com/problem/content/790/
#include <iostream>using namespace std;const int N = 100010;int temp[N];int a[N],n;long long reverseNum( int l, int r){//在归并排序的过程中,计算逆序对if(l >= r) return 0;int mid = l + r >> 1;long long num = reverseNum(l, mid) + reverseNum(mid + 1, r);//int k=0, i = l, j = mid + 1;while(i <= mid && j <= r){if(a[i] <= a[j]){//在该步骤判断是否逆序temp[k++] = a[i++];}else{temp[k++] = a[j++];num += mid - i + 1;}}while(i <= mid) temp[k++] = a[i++];while(j <= r) temp[k++] = a[j++];for(int i = l,k = 0; i <= r; i++, k++)a[i]=temp[k];return num;}int main(){cin >> n;for(int i = 0; i < n; i++ ) cin >> a[i];cout << reverseNum(0, n-1) << endl;return 0;}
分析
归并算法的基本思想 左右两组进行对比,即分治算法。在每次循环的时候,左右两组均为有序。自底向上,最底层的两组,即两个数字m和n,左右两组各有一个数字,这自然是有序的。自此由下往上,使用归并算法,使得每组均有序。
在求逆序数的过程中,我们只需关注,左右两组的数字作比较,即左边的某一个数字a[i]开始大于右边的a[j],此时i到mid均大于j。
总结
思想简单,但理解起来略有难度,比较绕
