题目描述
猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。
输入输出格式
输入格式:第一行,一个数n,表示序列中有n个数。
第二行n个数,表示给定的序列。
输出格式:给定序列中逆序对的数目。
输入输出样例
6 5 4 2 6 3 1
11
说明
对于50%的数据,n≤2500
对于100%的数据,n≤40000。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn=1000000+10;
int a[maxn],tmp[maxn],ans;
void gbpx(int l,int r){
if(l==r)return;
int mid=(l+r)/2;
gbpx(l,mid);gbpx(mid+1,r);
int i=l,j=mid+1,k=0;
while(i<=mid&&j<=r){
if(a[i]<a[j]){tmp[++k]=a[i];i++;}
else {
ans+=mid-i+1;
tmp[++k]=a[j];j++;
}
}
for(int u=i;u<=mid;u++)tmp[++k]=a[u];
for(int u=j;u<=r;u++)tmp[++k]=a[u];
for(int i=1;i<=k;i++)a[l+i-1]=tmp[i];
}
int main(){
int i,n;
cin>>n;
for(i=1;i<=n;i++)scanf("%d",&a[i]);
gbpx(1,n);
cout<<ans;
return 0;
}