7622:求排列的逆序数 C++
题目链接http://noi.openjudge.cn/ch0204/7622/
该题只需先进行归并排序,因为如果a[p1]>a[p2]说明a[p2]比区间[p1,m]中的任何元素都小,且p1在p2之前,所以能得出m-p1+1个逆序对。所以在合并区间时加上tot+=mid-i+1; 即可 参考代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <cctype> #include <algorithm> using namespace std; long long cnt=0; void Merge(long long a[],int s,int m,int e,long long tmp[]) { int pb=0,p1=s,p2=m+1; while(p1<=m&&p2<=e) { if(a[p1]<=a[p2]) {tmp[pb++]=a[p1++]; } else {tmp[pb++]=a[p2++];cnt+=m-p1+1;} } while(p1<=m) {tmp[pb++]=a[p1++]; } while(p2<=e) {tmp[pb++]=a[p2++]; } for(int i=0;i<e-s+1;++i) { a[s+i]=tmp[i]; } } void Mergesort(long long a[],int s,int e,long long tmp[]) { if(s<e) { int m=s+(e-s)/2; Mergesort(a,s,m,tmp); Mergesort(a,m+1,e,tmp); Merge(a,s,m,e,tmp); } } int main() { int n; long long a[100010],b[100010]; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%lld",&a[i]); } Mergesort(a,0,n-1,b); printf("%lld\n",cnt); return 0; }