大三下每日打卡027

788.逆序对的数量

给定一个长度为 nn 的整数数列,请你计算数列中的逆序对的数量。

逆序对的定义如下:对于数列的第 ii 个和第 jj 个元素,如果满足 i<ji<j 且 a[i]>a[j]a[i]>a[j],则其为一个逆序对;否则不是。

输入格式

第一行包含整数 nn,表示数列的长度。

第二行包含 nn 个整数,表示整个数列。

输出格式

输出一个整数,表示逆序对的个数。

数据范围

1≤n≤1000001≤n≤100000, 数列中的元素的取值范围 1,109

输入样例:

6
2 3 4 5 6 1

输出样例:

5
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=100010;
int q[N],tmp[N];

LL merge_sort(int q[],int l,int r)
{
   if(l>=r) return 0;
   int mid=l + r>>1;
   LL res=merge_sort(q,l,mid)+merge_sort(q,mid+1,r);//左半边内部逆序对数+右半边内部逆序对数
   //下面求在左右两边的逆序对数
   int k=0,i=l,j=mid+1;
   while(i<=mid&&j<=r)
  {
       if(q[i]<=q[j])tmp[k++]=q[i++];
       else
      {
           res +=mid - i + 1;
           tmp[k++]=q[j++];
      }
  }
   while(i<=mid)tmp[k++]=q[i++];
   while(j<=r)tmp[k++]=q[j++];
   //返回原数组
   for(int i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];
   return res;
}

int main()
{
   int n;
   scanf("%d", &n);
   for(int i=0;i<n;i++)scanf("%d",&q[i]);
   cout<<merge_sort(q,0,n-1)<<endl;
   return 0;
}
 
posted @ 2025-04-01 11:51  软件拓荒人  阅读(8)  评论(0)    收藏  举报