1203: 逆序数 ( 归并排序 )

1203: 逆序数

Time Limit: 1 Sec Memory Limit: 128 MB

Submit: 125 Solved: 26

[Submit][Status][Web Board]

Description

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

如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。

Input

多组测试数据

每组测试数据分两行,第一行一个正整数n(n <= 50000)

第二行有n个元素( 0 <= A[i] <= 10^9)

Output

每组测试数据输出一行表示逆序数

Sample Input

4

2 4 3 1

3

1 1 1

Sample Output

4

3

//注意题目中的红色的部分,对应代码修改红色的地方,一般情况下是<=的关系

#include<cstdio>
#include<algorithm>
//#include<bits/stdc++.h>
using namespace std;
template<class T>inline T read(T&x)
{
    char c;
    while((c=getchar())<=32)if(c==EOF)return 0;
    bool ok=false;
    if(c=='-')ok=true,c=getchar();
    for(x=0; c>32; c=getchar())
        x=x*10+c-'0';
    if(ok)x=-x;
    return 1;
}
template<class T> inline T read_(T&x,T&y)
{
    return read(x)&&read(y);
}
template<class T> inline T read__(T&x,T&y,T&z)
{
    return read(x)&&read(y)&&read(z);
}
template<class T> inline void write(T x)
{
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x+'0');
    else write(x/10),putchar(x%10+'0');
}
template<class T>inline void writeln(T x)
{
    write(x);
    putchar('\n');
}
//-------ZCC IO template------
const int maxn=50011;
const double inf=999999999;
#define lson (rt<<1),L,M
#define rson (rt<<1|1),M+1,R
#define M ((L+R)>>1)
#define For(i,t,n) for(int i=(t);i<(n);i++)
typedef long long  LL;
typedef double DB;
typedef pair<int,int> P;
#define bug printf("---\n");
#define mod 10007

int ans=0;
void merge_sort(int *A,int x,int y,int *T)
{
    if(y-x>1)
    {
        int p=x,m=(x+y)/2;
        int i=x;
        int q=m;
        merge_sort(A,x,m,T);
        merge_sort(A,m,y,T);
        while(p<m||q<y)
        {
            if(q>=y||(p<m&&<span style="color:#FF0000;">A[p]<A[q]</span>))T[i++]=A[p++];
            else {T[i++]=A[q++];ans+=m-p;}
        }
        for(int i=x;i<y;i++)
            A[i]=T[i];
    }
}
 int a[maxn];
 int b[maxn];
int main()
{
    #ifndef ONLINE_JUDGE
   // freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int n,m,i,j,k,t;
    while(read(n))
    {
        For(i,0,n)
        {
            read(a[i]);
        }
        ans=0;
        merge_sort(a,0,n,b);
        writeln(ans);
    }
    return 0;
}
时间: 2024-11-04 19:55:54

1203: 逆序数 ( 归并排序 )的相关文章

逆序数(归并排序)

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如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 这题用归并排序做

nyist oj 117 求逆序数 (归并排序&amp;&amp;树状数组)

求逆序数 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出它的逆序数是多少. 比如 1 3 2 的逆序数就是1. 输入 第一行输入一个整数T表示测试数据的组数(1<=T<=5) 每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000) 随后的一行共有N个整

51Nod 1019 逆序数 (归并排序)

1 #include <iostream> 2 #include <cstring> 3 4 using namespace std; 5 const int maxn = 50005; 6 int a[maxn]; 7 int res[maxn]; 8 int ans; 9 10 //归并排序 11 void merge(int l, int r){ 12 //cout<<l<<" "<<r<<endl; 13

归并排序——计算逆序数

归并排序——计算逆序数 归并排序用了分治的思想,时间复杂度o(N*logN)动态内存的运用可减小空间开销: 归并排序还可用于计算逆序数: 逆序数:序列中位置和大小相反的一对数字: 逆序数=冒泡排序中相邻两个数字交换的次数: int a[maxn],n; long long ans; //逆序数一般很大,用long long void compute_ans(int*a,int begin,int mid,int end) { int len_L=mid-begin+1; int len_R=en

poj 2299 逆序数

http://poj.org/problem?id=2299 坑:答案是long long 输出……!!!!! 题意是:求一个数组进行冒泡排序交换的次数 题解:求逆序数 题解Ⅰ: 归并排序求逆序数 归并排序求逆序数之前写过 1.归并排序是把两个有序的数组合并成为一个有序的数组,利用分治的思想就可以进行排序 逆序数可以利用这个思想求 求出第一个数组的逆序数,和第二个数组的逆序数,再将两个数组整体的逆序数求出来 f(x,y) = f(x,mid) + f(mid,y) + 之后数组的逆序数 #inc

归并排序_逆序数

归并排序求逆序数 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数.一个排列中所有逆序总数叫做这个排列的逆序数.也就是说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时,就说有1个逆序.一个排列中所有逆序总数叫做这个排列的逆序数. 1 #include<cstdio> 2 #in

求逆序数(归并排序)

求逆序数 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出它的逆序数是多少. 比如 1 3 2 的逆序数就是1. 输入 第一行输入一个整数T表示测试数据的组数(1<=T<=5) 每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000) 随后的一行共有N个整

【上海交大oj】逆序数对(归并排序)

3021. 逆序数对 Description 给你一个数组,求该数组的逆序数 Input Format 输入文件第一行包含一个自然数N,N个数 接下来有N行,表示a[0],a[1]...a[n - 1] Output Format 输出文件仅有一行包含一个整数,表示该数组的逆序数 Sample Input 3 575085724 344369358 808884464 Sample Output 1==============================================所谓逆

poj 2299 Ultra-QuickSort 归并排序求逆序数对

题目链接: http://poj.org/problem?id=2299 题目描述: 给一个有n(n<=500000)个数的杂乱序列,问:如果用冒泡排序,把这n个数排成升序,需要交换几次? 解题思路: 根据冒泡排序的特点,我们可知,本题只需要统计每一个数的逆序数(如果有i<j,存在a[i] > a[j],则称a[i]与 a[j]为逆序数对),输出所有的数的逆序数的和用普通排序一定会超时,但是比较快的排序,像快排又无法统计 交换次数,这里就很好地体现了归并排序的优点.典型的利用归并排序求逆