POJ 2299 Ultra-QuickSort 分治法求逆序数
2015-01-23 09:31
507 查看
题意:给出一个数组,求出该数组的逆序对的个数。
思路:我们用分治法来求解该题。对于数组A,我们将其二等分成B,C两个数组,则逆序对位于下面的三种情况之一
1.位于数组B中,2.位于数组C中。3.一个位于B中,一个位于C中。
对于前两种情况,我们可以递归处理,所以我们只需考虑的是第三种情况,就是对于C中每个数字,考虑B中有多少个比他大。可以用归并排序来完成上面的过程。
代码如下:
思路:我们用分治法来求解该题。对于数组A,我们将其二等分成B,C两个数组,则逆序对位于下面的三种情况之一
1.位于数组B中,2.位于数组C中。3.一个位于B中,一个位于C中。
对于前两种情况,我们可以递归处理,所以我们只需考虑的是第三种情况,就是对于C中每个数字,考虑B中有多少个比他大。可以用归并排序来完成上面的过程。
代码如下:
#include <cstdio> #include <algorithm> #include <cstring> #include <vector> using namespace std; typedef long long ll; int N; vector<int> A; ll mergesort(vector<int> &a) { int n = a.size(); if(n <= 1) return 0; ll cnt = 0; vector<int> b(a.begin(),a.begin() + n / 2); vector<int> c(a.begin() + n / 2, a.end()); cnt += mergesort(b); cnt += mergesort(c); int ai = 0, bi = 0, ci = 0; while(ai < n){ if(bi < b.size() && (ci == c.size() || b[bi] <= c[ci])) a[ai++] = b[bi++]; else{ cnt += n / 2 - bi; a[ai++] = c[ci++]; } } return cnt; } int main(void) { //freopen("input.txt","r",stdin); while(scanf("%d",&N),N){ A.resize(N); for(int i = 0; i < N; ++i) scanf("%d",&A[i]); printf("%lld\n",mergesort(A)); } return 0; }
相关文章推荐
- (应用排序算法编程7.2.2)POJ 2299 Ultra-QuickSort(使用归并排序来计算逆序对的个数)
- 【原】 POJ 2299 Ultra-QuickSort 逆序数 解题报告
- POJ 2299 Ultra-QuickSort 【归并排序求逆序数 OR 树状数组求逆序数】
- poj_2299 Ultra-QuickSort(归并排序/树状数组 求逆序对)
- poj 2299 Ultra-QuickSort【归并排序求逆序数】
- POJ 2299 Ultra-QuickSort (树状数组求逆序数 || 线段树 +离散化)
- poj 2299 Ultra-QuickSort(求逆序数,树状数组)
- POJ-2299 Ultra-QuickSort 逆序对统计
- POJ - 2299 Ultra-QuickSort —— 逆序对
- poj 2299 Ultra-QuickSort(fenwick树求逆序对)
- POJ:2299 Ultra-QuickSort(树状数组+离散化+技巧+求逆序对)
- POJ 2299 Ultra-QuickSort(归并排序·树状数组·逆序对)
- POJ 2299 Ultra-QuickSort 求逆序对数(归并排序,树状数组)
- POJ 2299 Ultra-QuickSort(求逆序对)
- poj 2299 Ultra-QuickSort(求逆序数,树状数组)
- poj 2299 Ultra-QuickSort——归并排序求逆序数,线段树离散化
- POJ-2299 Ultra-QuickSort-分治法排序求交换速度
- POJ 2299 Ultra-QuickSort ---归并排序 求逆序
- POJ2299 Ultra-QuickSort(树状数组求逆序数+离散化)
- POJ 2299 Ultra-QuickSort 【归并排序求逆序对数】