码迷,mamicode.com
首页 > 其他好文 > 详细

AKOJ-2021-逆序对(归并,二分)

时间:2019-01-18 13:34:04      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:方法   std   int   归并   pre   space   name   优先   else   

链接:https://oj.ahstu.cc/JudgeOnline/problem.php?id=2021

题意:

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

现在,给你一个N个元素的序列,请你判断出它的逆序数是多少。

比如 1 3 2 的逆序数就是1。

思路:

求逆序对,之前用树状数组写过,此解使用归并排序的方法求解。

不断对原数组进行二分,即先求解原数组左边数组和右边数组的逆序对数。

当对数组合并时,寻找左边数组比右边数组值大的数,优先处理左边数组,即Left[i] <= Right[j]。

当两值相等时不满足逆序对,所以优先将左边数组相等之加入原数组,

同时累计sum += j-1。

代码:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000000+10;
int Left[MAXN/2],Right[MAXN/2],a[MAXN];
int n;
long long sum = 0;
void Megre(int p,int q,int r)
{
    int w;
    for (int i = p,w = 1;i<=q;i++)
        Left[w++] = a[i];
    for (int i = q+1,w = 1;i<=r;i++)
        Right[w++] = a[i];
    int i = 1,j = 1;
    w = p;
    while (w <= r)
    {
        if (j > r-q || i <= q-p+1&&Left[i] <= Right[j])//当两值相等时优先处理左边数组
        {
            a[w] = Left[i];
            i++;
            sum += j-1;//右边数组往后移动位数即右边比左边当前位置值小的值个数
        }
        else
        {
            a[w] = Right[j];
            j++;
            //sum += i-1;
        }
        w++;
    }
}

void Megre_sort(int p,int r)
{
    if (p < r)
    {
        int q = (p + r) / 2;
        Megre_sort(p, q);
        Megre_sort(q + 1, r);
        Megre(p, q, r);
        /*
        cout << p << ‘ ‘ << r << ‘:‘ << endl;
        cout << sum << endl;
         */
    }
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        cin >> n;
        for (int i = 1;i<=n;i++)
            cin >> a[i];
        sum = 0;
        Megre_sort(1,n);
        cout << sum << endl;
    }

    return 0;
}

  

AKOJ-2021-逆序对(归并,二分)

标签:方法   std   int   归并   pre   space   name   优先   else   

原文地址:https://www.cnblogs.com/YDDDD/p/10287121.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!