归并排序:
#include<iostream>
using namespace std;
int num[1005]; //输入数组&答案数组
int temp[1005]; //中转数组
void merge(int l,int r,int mid)
{
int i=l,j=mid,p=l;
while(i<mid&&j<r)//左右两边打擂
{
if(num[i]<num[j])//左边输了(左边比较小)
temp[p++]=num[i++]; //将左边输了的元素放到有序数组中
else//右边输了(右边比较小)
temp[p++]=num[i++];//将右边输了的元素放到有序数组中
}
while(i<mid) //看看左边是否还有余党
{
temp[p++]=num[i++];//因为一定是有序的,所以直接放进去就好
}
while(j<=r) //看看右边是否还有余党
{
temp[p++]=num[j++];//因为一定是有序的,所以直接放进去就好
}
p=l;
i=l;
while(p<=r) //将排序好的temp数组复制到num答案数组中
{
num[i++]=temp[p++];
}
}
void merge_sort(int l,int r)
{
if(l<r)
{
int mid=(l+r)/2;//计算中间元素的下标
merge_sort(l,mid);//递归拆分左边
merge_sort(mid+1,r);//递归拆分右边
merge(l,r,mid+1);//拆分完毕,开始归并
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>num[i];
}
merge_sort(1,n);
for(int i=1;i<=n;++i)
{
cout<<num[i]<<" ";
}
return 0;
}
基于归并排序的求解逆序对模板(学长写的):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e6;
const int mod = (int)1e8 + 7;
int n;
ll a[M + 5];
ll b[M + 5];
ll merge_sort(ll a[], int l, int r)
{
if(l >= r) return 0;
int mid = (l + r) >> 1; ll cnt = (merge_sort(a, l, mid) + merge_sort(a, mid + 1, r)) % mod;
int i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r) if(a[i] <= a[j]) b[++k] = a[i++]; else b[++k] = a[j++], (cnt += mid - i + 1) %= mod;
while(i <= mid) b[++k] = a[i++];
while(j <= r) b[++k] = a[j++];
for(int i = l, j = 1; i <= r; ++i, ++j) a[i] = b[j];
return cnt;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
printf("%lld\n", merge_sort(a, 1, n));
return 0;
}
还有一个长得和归并排序差不多的:
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const ll maxn=1000000;
const ll mod=100000007;
ll s1[maxn+5];
ll s2[maxn+5];
ll cnt=0;
void merge(ll L, ll R, ll Mid){
ll i = L;ll j = Mid + 1;ll k = L;
while(i <= Mid && j <= R){
if(s1[i] <= s1[j])s2[k ++] = s1[i ++];
else{
cnt += Mid - i + 1;
//对于i到Mid这Mid - i + 1个数字(假设它为j),每一个a[j]都与a[i]构成了一个逆序对
s2[k ++] = s1[j ++];
}
}
while(i <= Mid)s2[k ++] = s1[i ++];
//对于每个j都已讨论完,每个j钱比他大的数都已计入cnt,所以此时不用更新cnt
while(j <= R)s2[k ++] = s1[j ++];
for(i = L; i <= R; i ++)s1[i] = s2[i];
}
void mergesort(ll L,ll R){
if(L < R){
ll Mid = (L + R) / 2;
mergesort(L, Mid),mergesort(Mid + 1, R);
merge(L, R, Mid);
}
}
int main(){
ll n;
scanf("%lld", &n);
for(ll i = 1; i <= n; i ++)scanf("%lld", &s1[i]);
mergesort(1, n);
printf("%lld", cnt%mod);
}