数组中的逆序对
Problem Description
给定一组数,其中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
Input
首先输入数据组数T(1<=T<=100)
每组测试数据包括两行:第一行包含一个整数n,表示数组中的元素个数。其中1 <= n <= 10^5。
第二行包含n个整数,每个数组均为int类型。
Output
对应每组测试数据,输出一个整数,表示数组中的逆序对的总数。注意,结果比较大,请用long long!
Sample Input
1 4 7 5 6 4
Sample Output
5
主要思想:用归并把数组从小到大排序;当R[j]<L[i]时;必然有N1-i个逆序数;总计即可;<strong>#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<stack> using namespace std; long long sum; int a[100010]; void merge(int *a,int l,int mid,int r) { int n1=mid-l+1; int n2=r-mid; int *L=new int[n1+1]; int *R=new int [n2+1]; int i,j,k; for(i=0; i<n1; i++) { L[i]=a[i+l]; } for(j=0; j<n2; j++) { R[j]=a[j+mid+1]; } for(i=0,j=0,k=l; k<=r&&i<n1&&j<n2; k++) { if(L[i]<=R[j]) { a[k]=L[i++]; } else { sum+=(n1-i); a[k]=R[j++]; } } if(i>=n1) { while(k<=r) { a[k++]=R[j++]; } } else { while(k<=r) { a[k++]=L[i++]; } } delete []L; delete []R; } void merge_sort(int *a,int l,int r) { if(l<r) { int mid=(l+r)>>1; merge_sort(a,l,mid); merge_sort(a,mid+1,r); merge(a,l,mid,r); } } int main() { int n,t; while(~scanf("%d",&t)) { while(t--) { sum=0; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d",&a[i]); } merge_sort(a,0,n-1); printf("%lld\n",sum); } } return 0; </strong>