归并排序模板
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 100010;
int q[N],t[N]; //q是原数组和最终数组,t是中间暂存数组
void merge_sort(int q[],int l,int r)
{
if(l>=r) return; //递归的终点,即数组中没有数或者只有1个数了停止
int mid=l+r>>1;
merge_sort(q,l,mid),merge_sort(q,mid+1,r);
int k=0;
int i=l,j=mid+1;
while (i<=mid&&j<=r) //双指针
{
if (q[i]<=q[j]) t[k++]=q[i++];
else t[k++]=q[j++];
}
while (i<=mid) t[k++]=q[i++];
while (j<=r) t[k++]=q[j++];
for (int i=l,j=0;i<=r;i++,j++) //将暂存数组的数据赋值到原数组中
q[i]=t[j];
}
int main()
{
int n;
scanf("%d",&n);
for (int i=0;i<n;i++)
scanf("%d",&q[i]);
merge_sort(q,0,n-1);
for (int i=0;i<n;i++)
printf("%d ",q[i]);
printf("\n");
return 0;
}
归并排序的重要应用(逆序对个数求解)
788.逆序对的数量
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 100010;
int q[N],t[N];
long long merge_sort(int l,int r)
{
if (l>=r) return 0;
int mid=l+r>>1;
long long ans=merge_sort(l,mid)+merge_sort(mid+1,r);
int k=0;
int i=l,j=mid+1;
while (i<=mid&&j<=r)
{
if (q[i]<=q[j]) t[k++]=q[i++];
else //此时q[i]>q[j],即i~mid的所有数字都比q[j]大,因此可构成mid-i+1个逆序对
{
t[k++]=q[j++];
ans+=mid-i+1;
}
}
while (i<=mid) t[k++]=q[i++];
while (j<=r) t[k++]=q[j++];
for (int i=l,j=0;i<=r;i++,j++)
q[i]=t[j];
return ans;
}
int main()
{
int n;
cin>>n;
for (int i=0;i<n;i++)
cin>>q[i];
cout<<merge_sort(0,n-1)<<endl;
return 0;
}