7-8 逆序对 (10 分)
求逆序对。
输入格式:
第一行是一个整数n,(n<=1000,000)表示输入序列的长度,接下来一行是n个整数(每个数的绝对值小于)。
输出格式:
一个数,表示逆序对个数(逆序即任意一对数前面的数比后面的数大即为一对逆序对)。
输入样例:
在这里给出一组输入。例如:
10 1 3 5 7 9 8 4 2 6 10
输出样例:
在这里给出相应的输出。例如:
14
说明:样例中如1和3不是逆序对,而3和2是1对逆序对,例子中共有14对逆序对。题目中可能有某些数字出现多次的情况。
作者
严华云
单位
湖州师范学院
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
#include<bits/stdc++.h> using namespace std; int a[1000002],b[1000002]; long long cnt=0; void merge(int l,int r){ int m,k,k1,k2,t; m=(l+r)/2; k1=l; k2=m+1; k=l; while(k1<=m&&k2<=r){ if(a[k1]<=a[k2]){ b[k]=a[k1]; k++; k1++; } else{ b[k]=a[k2]; k++; k2++; cnt=cnt+m-k1+1; } } while(k1<=m){ b[k]=a[k1]; k++; k1++; } while(k2<=r){ b[k]=a[k2]; k++; k2++; } for(t=l;t<=r;t++){ a[t]=b[t]; } } void mergesort(int l,int r){ if(l<r){ int m; m=(l+r)/2; mergesort(l,m); mergesort(m+1,r); merge(l,r); } } int main(){ int n,i; cin>>n; for(i=1;i<=n;i++) scanf("%d",&a[i]); mergesort(1,n); printf("%lld",cnt); return 0; }