归并排序的思想是先分块,再合并。这样能大大降低复杂度
分块的复杂度是logn,合并的复杂度是n,因此总复杂度为nlgn
具体可以看代码的注释
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
int a[(int)1e5+5],tmp[(int)1e5+5];
ll ans=0;
void merge(int l,int r)
{
//合并时,l到mid,mid+1到r已经排好序了
//就只需要用两个类似指针的int,和一个tmp数组进行l到r的排序
int mid=(l+r)/2;
int p1=l,p2=mid+1;
int k=l;
while(k<=r)
{
//谁小就把值赋给当前的tmp[k],
//或者一边的已经分配完了,那么就全给另一边
if((p2<=r&&a[p1]>a[p2])||p1>mid)
tmp[k++]=a[p2++];
else
tmp[k++]=a[p1++];
}
//将tmp赋给a
for(int i=l;i<=r;++i)
a[i]=tmp[i];
return;
}
void divide(int l,int r)
{
if(l>=r)
return;
int mid=(l+r)/2;
divide(l,mid);
divide(mid+1,r);
merge(l,r);
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;++i)
scanf("%d",&a[i]);
divide(0,n-1);
cout<<ans<<endl;
}