求逆序数
求逆序數
時間限制:2000 ms ?|? 內存限制:65535 KB 難度:5 描述在一個排列中,如果一對數的前后位置與大小順序相反,即前面的數大于后面的數,那么它們就稱為一個逆序。一個排列中逆序的總數就稱為這個排列的逆序數。
現在,給你一個N個元素的序列,請你判斷出它的逆序數是多少。
比如 1 3 2 的逆序數就是1。
每組測試數據的每一行是一個整數N表示數列中共有N個元素(2〈=N〈=1000000)
隨后的一行共有N個整數Ai(0<=Ai<1000000000),表示數列中的所有元素。
數據保證在多組測試數據中,多于10萬個數的測試數據最多只有一組。
#include <iostream>
using namespace std;
#define MAX 1000010
#define MN 1000000050
__int64 sum;?int a[MAX];
int L[MAX/2],R[MAX/2];
void merge(int A[],int p,int q,int r)
{
?int n1=q-p+1,n2=r-q,i,j;?
?for (i=1;i<=n1;i++)
??L[i]=A[p+i-1];
?for (i=1;i<=n2;i++)
??R[i]=A[q+i];
?R[n2+1]=L[n1+1]=MN;
?i=j=1;
?for (int k=p;k<=r;k++)
?{
??if(L[i]<=R[j])
???A[k]=L[i++];
??else
??{
???A[k]=R[j++];
???sum+=n1-i+1;
??}
?}
}
void merge_sort(int A[],int p,int r)
{
?int q;
?if(p<r)
?{
??q=(p+r)>>1;
??merge_sort(A,p,q);
??merge_sort(A,q+1,r);
??merge(A,p,q,r);
?}
}
int main()
{
?int t,i,n,num,k;
?scanf("%d",&t);?
?while(t--)
?{??
??scanf("%d",&n);sum=0;
??for(i=1;i<=n;i++)
??{
???scanf("%d",&a[i]);???
??}
??merge_sort(a,1,n);
??printf("%I64d\n",sum);
?}
?return 0;
}
轉載于:https://www.cnblogs.com/qijinbiao/archive/2011/10/15/2213009.html
總結
- 上一篇: 电子病历开发经验共享 —— 2009年一
- 下一篇: UVA 10594 Data Flow