P1908 逆序对(离散化)

洛谷P1908 逆序对

在这里插入图片描述
在这里插入图片描述
逆序对就不用解释了,题上也说的很清楚。那我分别用归并排序和树状数组来解决一下这道题目。
归并排序
我们都知道,归并排序是通过把大区间一直分,分成小区间,然后小区间排序好了之后,再合并成大区间。也就是说在n*logn的复杂度的情况下给这个数组排了一下序列,在排序过程中加上一句代码ans+=mid-left+1,只要排在后面但是比前面的数小,位置差就是逆序数。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;
const int N=5e5+10;
int a[N],s[N];
long long ans;
void msort(int l,int r)
{
    if(l==r)
    {
        return;
    }
    int mid=(l+r)>>1;
    msort(l,mid);
    msort(mid+1,r);
    int i=l,j=mid+1,k=l;
    while(i<=mid&&j<=r)
    {
        if(a[i]<=a[j])
        {
            s[k]=a[i];
            i++,k++;
        }
        else
        {
            s[k]=a[j];
            j++,k++;
            ans+=mid-i+1;
        }

    }
    while(i<=mid)
    {
        s[k]=a[i];
        k++,i++;
    }
    while(j<=r)
    {
        s[k]=a[j];
        k++,j++;
    }
    for(int q=l;q<=r;q++)
    {
        a[q]=s[q];
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    ans=0;
    msort(1,n);
    printf("%lld\n",ans);
    return 0;
}

树状数组
用树状数组,因为这道题数据的值域有点大,但是数量并不是很多,所以要对数据进行离散化处理,离散化之后,对数据进行插入,插入的时候,随便求一下当前这个数前面已经插入了多少个数,然后用这个数的位置来减去前面的数的个数,就是这个数的逆序数,所有的数的逆序数之和就是这整个数列的逆序数。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;
const int N=5e5+10;
int a[N],s[N];
long long ans;
void msort(int l,int r)
{
    if(l==r)
    {
        return;
    }
    int mid=(l+r)>>1;
    msort(l,mid);
    msort(mid+1,r);
    int i=l,j=mid+1,k=l;
    while(i<=mid&&j<=r)
    {
        if(a[i]<=a[j])
        {
            s[k]=a[i];
            i++,k++;
        }
        else
        {
            s[k]=a[j];
            j++,k++;
            ans+=mid-i+1;
        }

    }
    while(i<=mid)
    {
        s[k]=a[i];
        k++,i++;
    }
    while(j<=r)
    {
        s[k]=a[j];
        k++,j++;
    }
    for(int q=l;q<=r;q++)
    {
        a[q]=s[q];
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    ans=0;
    msort(1,n);
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43402296/article/details/104235459