-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
对于一个长度为N的整数序列A,满足1<=i<j<=n且ai>Aj的数对(i,j)称为整数序列A的一个逆序
请求出整数序列A的所有逆序对个数
输入
-
输入包含多组测试数据,每组测试数据有两行
第一行为整数N(1<=N<=20000),当输入0时结束
第二行为N个整数,表示长为N的整数序列
输出
- 每组数据对应一行,输出逆序对的个数 样例输入
-
5 1 2 3 4 5 5 5 4 3 2 1 1 1 0
样例输出
0 10 0
归并排序的方法。
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<assert.h> #include<ctype.h> #include<stdlib.h> #define N 200007 using namespace std; int a[N],b[N]; int cnt=0; void he(int s1,int e1,int s2,int e2) { int p1=s1,p2=s2; int t=0; while(p1<=e1&&p2<=e2){ if( a[p1] <= a[p2] ){ b[t++] = a[p1++];} else {b[t++] = a[p2++];cnt += e1-p1+1;} } while(p1<=e1)b[t++] = a[p1++]; while(p2<=e2)b[t++] = a[p2++]; for(int i=s1;i<=e2;i++)a[i]=b[i-s1]; } void fen(int s,int e) { if(s<e) { int m=(s+e)/2; fen(s,m); fen(m+1,e); he(s,m,m+1,e); } } int main(){ int n; //freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF&&n!=0){ cnt=0; int i=0; for( i = 0; i < n; i++) scanf("%d",&a[i]); fen( 0, n-1 ); printf("%d\n",cnt); } return 0; }