nyoj-117-求逆序數
阿新 • • 發佈:2019-01-03
求逆序數
時間限制:2000 ms | 記憶體限制:65535 KB
難度:5
描述
在一個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為一個逆序。一個排列中逆序的總數就稱為這個排列的逆序數。
現在,給你一個N個元素的序列,請你判斷出它的逆序數是多少。
比如 1 3 2 的逆序數就是1。
輸入
第一行輸入一個整數T表示測試資料的組數(1<=T<=5)
每組測試資料的每一行是一個整數N表示數列中共有N個元素(2〈=N〈=1000000)
隨後的一行共有N個整數Ai(0<=Ai<1000000000),表示數列中的所有元素。
資料保證在多組測試資料中,多於10萬個數的測試資料最多隻有一組。
輸出
輸出該數列的逆序數
樣例輸入
2
2
1 1
3
1 3 2
樣例輸出
0
1
來源
上傳者
就是歸併排序
程式碼:
#include<stack> #include<queue> #include<cmath> #include<string> #include<cstdio> #include<vector> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=1e6+10; typedef long long ll; int a[N],b[N],c[N]; ll ans=0; void hebingsort(int l,int r) { if(l==r) return ; int mid=(l+r)>>1; hebingsort(l,mid); hebingsort(mid+1,r); int i=l,j=mid+1,k=l; while(i<=mid&&j<=r) { if(a[i]<=a[j]) { c[k++]=a[i++]; } else { c[k++]=a[j++]; ans+=(mid-i+1); } } while(i<=mid) { c[k++]=a[i++]; } while(j<=r) { c[k++]=a[j++]; } for(i=l;i<=r;i++) a[i]=c[i]; } int main() { int test; scanf("%d",&test); while(test--) { int i,j,k,n; memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&a[i]); } ans=0; hebingsort(1,n); printf("%lld\n",ans); } return 0; }