逆序数(归并)

来源:互联网 发布:centos 自动获取ip 编辑:程序博客网 时间:2024/06/18 04:15
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。

Input

第1行:N,N为序列的长度(n <= 50000)第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9)

Output

 输出逆序数

Input示例

4
2
4
3
1

Output示例

4

链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1019

思路:今天一天都在做用归并求逆序数的题目,这道题和小朋友排队不同的是只是简单的求每个数的逆序数之和。也就是说只要在判定前面的大于后面的时候进行计算即可。

代码:

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>using namespace std;int nix[55000], cnt[55000];long long ans = 0;int MergeSort(int first, int last){    if(first < last)    {        int mid = (first + last)/2;        MergeSort(first,mid);        MergeSort(mid+1,last);        int temp = first;        int p = first, q = mid+1;        while(p <= mid && q <= last)        {            if(nix[p] <= nix[q])                cnt[temp++] = nix[p++];            else            {                cnt[temp++] = nix[q++];                ans += (mid - p + 1);            }        }        while(q <= last)            cnt[temp++] = nix[q++];        while(p <= mid)            cnt[temp++] = nix[p++];        for(int i=first; i<=last; i++)            nix[i] = cnt[i];    }    return 0;}int main(){    int n;    while(~scanf("%d",&n))    {        for(int i=0; i<n; i++)            cin >> nix[i];        memset(cnt, 0,sizeof cnt);        ans = 0;        MergeSort(0,n-1);        cout << ans << endl;    }    return 0;}
0 0
原创粉丝点击