牛客 逆序数 (归并排序)

题目描述在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。比如一个序列为4 5 1 3 2, 那么这个序列的逆序数为7,逆序对分别为(4, 1), (4, 3), (4, 2), (5, 1), (5, 3), (5, 2),(3, 2)。输入描述:第一行有一个整数n(1 <= n <= 100000), 然后第二行跟着n个整数,对于第i个数a[i],(0 <= a[i] <= 100000)。输出描述:输出这个序列中的逆序数

输入54 5 1 3 2

输出7

题目分析这是一个经典的归并排序的模板题,也是一个树状数组的模板题,但是我不会树状数组!!!,那我们现在来讲一下什么是归并排序。

  • 首先就是递归,递归将一个数组分为两部分,然后再次递归将分完之后的每一部分分为两部分,然后不断地递归,直到每部分只剩下一个元素为止。
  • 然后再从这无数个数据在逐渐的合并,用二路归并,每次归并我们都计算一下逆序对的数量然后累加,但是每次归并的数组都是临时数组,会在后面的归并中覆盖,二路归并前提是要是两个有序的数组,所以这就是为什么分到最后每一部分都是一个元素,因为一个元素再怎么都是有序的,然后从下往上去二路归并。
  • 那么如何求逆序对的数量呢,在二路归并的时候,如果后面的数跑到前面去了,我们就计算中间路过了多少个数,那么它前面就有多少个数比它大。

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100005;
ll a[maxn], b[maxn], cnt;
void merge(ll l, ll mid, ll r)
{
    ll i = l, j = mid + 1, t = 1;
    while (i <= mid && j <= r)
    {
        if (a[i] > a[j])
        {
            b[t++] = a[j++];
            cnt += mid - i + 1; //记录逆序对数量
        }
        else
            b[t++] = a[i++];
    }
    //一个子序列中的数都处理完了,另一个还没有,把剩下的直接复制过来
    while (i <= mid)
        b[t++] = a[i++];
    while (j <= r)
        b[t++] = a[j++];
    for (int i = r; i >= l; i--)
        a[i] = b[--t]; //把排好序的b数组复制回a数组
}
void mergesort(ll l, ll r)
{
    if (l == r)
        return;
    int mid = (l + r) >> 1; //平均分为两个子序列
    mergesort(l, mid);
    mergesort(mid + 1, r);
    merge(l, mid, r); //合并
}
int main()
{
    ll n, k;
    while (~scanf("%lld", &n))
    {
        cnt = 0;
        for (ll i = 1; i <= n; ++i)
            scanf("%lld", &a[i]);
        mergesort(1, n); //归并排序
        printf("%lld\n", cnt);
    }
    return 0;
}

全部评论

相关推荐

昨天 11:14
门头沟学院 Java
秋招现状:后端开发,多家大厂offer,但部分业务没有那么满意,也没有谈薪,也许最后也不会100%满意前期方向选择:由于父母对这个行业不懂,也没有相关认识的人,所以主要是兴趣驱动。这个时间段主要在大一到研一,多方面探索、尝试,了解需要具备什么技能。充实自己在什么时候都不会有错。行业现状调研:这个过程主要是在研一下到研二上。和爸妈沟通发现他们更愿意我找稳定的体制内,与自己的计划和性格严重不符,遂放弃与他们的沟通,自己通过各种方式了解情况,包括上网查阅、和学长学姐交流、在表白墙等交友墙发帖求大佬建议。能力与知识储备:该阶段往小了说可以说是在研一下到研二下一年内。但对我而言,往大了说可以说是贯穿大一到现在。从大一入学时专业是天坑专业,我就开始比别人更卷。offer选择:将各个offer都和家里人分享后,家里人并不能get到各个offer的好坏,给出的建议也十分主观。甚至还觉得华为是可能比这些offer好得多的,内心充满了不被理解的感觉。后来渐渐地遇到问题就不再和家里人沟通了,而是自己上网搜索与咨询。秋招冲互联网大厂的,可能大多是和我类似的情况。准备的时候手足无措,对行业的了解也只能从网上和身边学长求助,无数次感到自己无助又弱小。但是事实就是这么残酷,用人单位才不会管这些背后的资源差异。不过话说回来,这一行已经是最不看背景的了。为什么我根本不care类似公务员这种的所谓“社会地位”?因为我认为那在后续职业发展的很多时候要比拼的并不是个人的专业素养,而是又一定的背景和资源;而在大厂相对更加纯粹的技术岗位,我感到作为一个独立的“人”的努力和技术能力得到了认可,这方面的认同让我非常开心。
没有家庭托举的我是怎么找...
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务