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

OJ4TH|Inverse number:Reborn

时间:2018-03-15 15:12:31      阅读:446      评论:0      收藏:0      [点我收藏+]

标签:+=   lld   ios   pos   return   print   namespace   限制   ret   

时间限制: 1000 ms 内存限制: 65536 kb

总通过人数: 234 总提交人数: 340

 

题目描述

输入一个正整数n,随后给出一个长度为n的整数序列a1,a2,a3...an。求给定序列的逆序数。

概念回顾:

逆序对:数列a[1],a[2],a[3]…中的任意两个数a[i],aj,如果a[i]>a[j],那么我们就说这两个数构成了一个逆序对。

逆序数:一个数列中逆序对的总数。

输入

多组测试数据。对于每组测试数据,给出序列长度n,和一个长度为n的序列a1,a2,a3...an

(0<n<=10^6,保证ai在int范围内)

输出

对于每组数据,输出该序列的逆序数。

输入样例

7 
3 5 4 8 2 6 9

输出样例

6

Hint

1、用n^2的算法是不行不行滴╮(╯_╰)╭
2、分治法

题解

OIers都知道这题的意思就是用归并排序求逆序对。

不过我WA了两次,最后发现ans不能用int来存……坑。

 

代码

#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;

int a[1000005],b[1000005];
long long ans;

void merge_sort(int l,int r)
{
    if (l==r) return;
    int mid=(l+r)/2;
    merge_sort(l,mid); merge_sort(mid+1,r);
    int i=l,j=mid+1,k=l;
    while (i<=mid && j<=r)
    {
        if (a[i]<=a[j]) b[k++]=a[i++];
        else 
        {
            b[k++]=a[j++];
            ans+=mid-i+1;
        }
    }
    while (i<=mid) b[k++]=a[i++];
    while (j<=r) b[k++]=a[j++];
    for (int t=l; t<=r; ++t) a[t]=b[t];
}

int main()
{
    int n;
    while (scanf("%d",&n)!=EOF)
    {
        ans=0;
        for (int i=1; i<=n; i++) scanf("%d",&a[i]);
        merge_sort(1,n);
        printf("%lld\n",ans);
    }
    return 0;
}

OJ4TH|Inverse number:Reborn

标签:+=   lld   ios   pos   return   print   namespace   限制   ret   

原文地址:https://www.cnblogs.com/Shymuel/p/8573512.html

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