一道编程题:求逆序对的个数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道编程题:求逆序对的个数相关的知识,希望对你有一定的参考价值。

给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目
输入:第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数。
输出:两行,第一行为所有逆序对总数,第二行为本质不同的逆序对总数。
样例输入:
4
3
2
3
2

样例输出:
3
1
数据范围:N<=105。Ai<=105。时间限制为1s。

哪位大牛帮下忙,讲下怎么用归并排序或树状数组做,主要是第二问,麻烦讲详细的,有程序的最好,PASCAL和C++的都可以

#include<stdio.h>
#define N 105
void main()

int n,i,j,k=0,p,m=0;
int a[20];
scanf("%d",&n);
getchar();
for(i=0;i<n;i++)

scanf("%d",&a[i]);
getchar();

for(i=0;i<n;i++)
for(j=i+1;j<n;j++)

if(a[i]>a[j])
k++;

for(i=0;i<n;i++)/*去掉相同的元素,再进行排序*/
for(j=i+1;j<n;j++)

if(a[i]=a[j])

for(p=j+1;p<n;p++)
a[p-1]=a[p];
n--;


for(i=0;i<p;i++)
for(j=i+1;j<p;j++)

if(a[i]>a[j])
m++;


printf("%d\n%d",k,m);
//呵呵,我只会用c写,不过结果是对的。
参考技术A 6分之一,把26个数看成4个数来计算,
得出的答案是一样的,
就是六分之一
参考技术B 前面改成int main(),如果测试程序有时间限制的话,这个算法不够优化,时间超出限制,不过改之后是可以运行的

怎么求逆序对的数量呢?一种特殊写法告诉你

求逆序对的必备知识

我们要求逆序对,就要求前面的数比后面的数大的数对有多少个。

那么如果我们把每个数前面比它大的数有多少个求出来就可以了,答案就显而易见,就是每个数前面比它大的数的个数的和。

那么问题转化为求每个数前面比它大的数的个数。

怎么求呢?

我们考虑到可以用树状数组tr[]维护一个数组

先将原数组进行离散化,因为可能原数组的数据范围很大,数组空间不能开的很大。离散化之后原数组就变成了一个相对大小等级的数。(数小代表这个数值小相对其他数小)

然后每访问一个数,就把树状数组相对应等级的位置加一,代表该等级有一个数存在,然后i-sum(a[i])代表已经访问数的个数减去小于等于a[i]的数的个数(其实就是前面出现的大于a[i]的数的个数)

注意:树状数组存储的是数的大小等级(相对大小)

累加一下就好了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+5;
ll a[N],b[N],tr[N];
ll n;
void add(int p,int x)
{
    while(p<=n){tr[p]+=x;p+=p&-p;}
}
ll sum(int x)
{
    ll res = 0;
    while(x){res+=tr[x];x-=x&-x;}
    return res;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) {cin>>a[i];b[i]=a[i];}
    sort(b+1,b+1+n);//必须先排序才能去重
    int len = unique(b+1,b+1+n)-b-1;//去重
    for(int i=1;i<=n;i++)
        a[i] = lower_bound(b+1,b+1+len,a[i])-b;
    ll ans = 0;
    for(int i=1;i<=n;i++)
    {
        add(a[i],1);
        ans += i-sum(a[i]);
//        cout<<i-sum(a[i])<< "\\n";
    }
    cout<<ans<<'\\n';
    return 0;
}

以上是关于一道编程题:求逆序对的个数的主要内容,如果未能解决你的问题,请参考以下文章

归并排序C++实现及求逆序对的个数

逆序对的求解逆序对个数问题

codevs 4163 求逆序对的数目 -树状数组法

JNday7-am

怎么求逆序对的数量呢?一种特殊写法告诉你

归并排序应用-求逆序对数量