• AcWing 107. 超快速排序


    超快速排序

    一、引理:逆序数

    在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数

    排列的逆序数等于该排列转化为自然排序(从小到大)的最小次数
    例如:\(31425\) 的逆序数为\(3\)

    • \(3\)无逆序,则\(n_1 = 0\)

    • \(1\)逆序有\(3\),则\(n_2 = 1\)

    • \(4\)无逆序,则\(n_3 = 0\)

    • \(2\)逆序有\(3,4\),则\(n_4 = 2\)

    • \(5\)无逆序,则\(n_5 = 0\)

    若将该序列转化成从小到大排序,需要\(\large (n_1 + n_2 + n_3 + n_4 + n_5)=3\)次交换。

    二、直接计算

    计算一个排列的逆序数的直接方法是逐个枚举逆序,同时统计个数。例如在序列 \(\{3, 1, 4, 2, 5 \}\) 中,逆序依次为 \((3,1),(3,2),(4,3)\),因此该序列的逆序数为 \(3\)

    三、归并排序

    直接计数法虽然简单直观,但是其时间复杂度是\(O(n^2)\)。一个更快的计算方法是在归并排序的同时计算逆序数。且该方法只是交换相邻的两个元素,符合题意。

    四、算法分析

    归并排序

    • 给定两个有序序列,从右边序列中最小的元素开始往左边序列中插入,设右边序列中选定的元素的位置为j,左边序列选定的元素位置为i,中间位置为mid,则此时交换的位置次数是(mid - i + 1),最后把所有归并后交换的次数累加在一起即可。

    • 例如 \(31425\) 经过归并后得出两个有序序列 \(134\)\(25\) (注意:\(314\)也是需要归并交换位置得到\(123\)的)即将\(2\)插入到\(3\)位置前,此操作相当于交换了两次位置,设\(3\)元素的位置为\(i\)\(4\)元素的位置是中间位置\(mid\),则此时交换的次数为\((mid - i + 1) = 2\)

    附上主播的图

    五、实现代码

    #include <bits/stdc++.h>
    typedef long long LL;
    const int N = 500010;
    int n;
    LL q[N], tmp[N];
    
    LL merge_sort(int l, int r) {
        if (l >= r) return 0;
        int mid = (l + r) >> 1;
    
        LL res = merge_sort(l, mid) + merge_sort(mid + 1, r);
    
        int i = l, j = mid + 1, k = 0;
        while (i <= mid && j <= r)
            if (q[i] <= q[j])
                tmp[k++] = q[i++];
            else {
                res += mid - i + 1; //如果q[i]>q[j],那么 i~mid之间所有数字,都>q[j]
                tmp[k++] = q[j++];
            }
        //清理剩余
        while (i <= mid) tmp[k++] = q[i++];
        while (j <= r) tmp[k++] = q[j++];
        //抄回来
        for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
        return res;
    }
    
    int main() {
        while (scanf("%d", &n), n) {
            for (int i = 0; i < n; i++) scanf("%d", &q[i]);
            printf("%lld\n", merge_sort(0, n - 1));
        }
        return 0;
    }
    
    
  • 相关阅读:
    14-补充内容:MySQl创建用户和授权
    15-可视化工具Navicat的使用
    11-数据的增删改
    12-单表查询
    09-完整性约束
    10-外键的变种 三种关系
    07-数据类型
    08-数据类型(2)
    Mysql 基本语法
    E. K-periodic Garland
  • 原文地址:https://www.cnblogs.com/littlehb/p/16441707.html
Copyright © 2020-2023  润新知