首页 > 其他分享 >P1908 逆序对

P1908 逆序对

时间:2023-02-17 12:55:12浏览次数:40  
标签:P1908 int LL mid ++ 序列 逆序


题目描述

猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。
Update:数据已加强。

输入输出格式

输入格式:

 

第一行,一个数n,表示序列中有n个数。

第二行n个数,表示给定的序列。序列中每个数字不超过10910^9109

 

输出格式:

 

给定序列中逆序对的数目。

 

输入输出样例

输入样例#1: 复制


6 5 4 2 6 3 1


输出样例#1: 复制


11


说明

对于25%的数据,n≤2500

对于50%的数据,n≤4×10^4

对于所有数据,n≤5×10^5

请使用较快的输入输出

应该不会n方过50万吧 by chen_zhe

归并解法 : 

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const int MAX = 500005 ;
int n ;
LL a[MAX] ;
LL b[MAX] ;
LL ans = 0 ;
void merge_sort(int l ,int r ){
if(l ==r )return ;
LL mid = (l+r)/2 ;
merge_sort(l,mid) ;
merge_sort(mid+1,r) ;
int i = l , k = l , j =mid +1 ;
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 i = l; i<=r ; i++){
a[i] = b[i] ;
}
}
int main(){
scanf("%d",&n);
for(int i = 1 ; i<=n ; i++ ){
scanf("%lld",&a[i]);
}

merge_sort(1,n) ;
cout<<ans;
return 0 ;
}

 

 

标签:P1908,int,LL,mid,++,序列,逆序
From: https://blog.51cto.com/u_15970235/6063952

相关文章