逆序对裸题。可以用树状数组做,但树状数组是以数据的大小为下标,时间复杂度为O(n log n)(n=max(a[i])),总体来说还是归并好一些。
#include<cstdio> #include<cstring> int a[200005],b[200005],n,t; int i; long long ans; void count(int l,int r){ int m,i,j,k; if (l==r)return; m=(l+r)>>1; count(l,m);count(m+1,r); i=l;j=m+1;k=l-1; while(i<=m&&j<=r){ while(a[i]<=a[j]&&i<=m){ b[++k]=a[i++]; ans+=(j-m-1); } while(a[i]>a[j]&&j<=r){ b[++k]=a[j++]; } } while(i<=m){ b[++k]=a[i++]; ans+=(j-m-1); } for (i=l;i<j;i++)a[i]=b[i]; } int main(){ scanf("%d",&t); while(t--){ ans=0; scanf("%d",&n); for (i=1;i<=n;i++) scanf("%d",&a[i]); count(1,n); printf("%lld\n",ans); } }
时间: 2024-10-11 14:12:42