Basic steps:
1. Demarcation point mid=(l+r)/2
2. Recursive sorting (left, right)
3. Combine two into one
#include<cstdio>
#include<cmath>
#include<ctime>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#define ll long long
#define ull unsigned long long
#define up_b upper_bound
#define low_b lower_bound
#define m_p make_pair
#define mem(a) memset(a,0,sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
#include<algorithm>
using namespace std;
inline ll read()
{
ll x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1; ch=getchar(); }
while('0'<=ch&&ch<='9') x=x*10+ch-'0', ch=getchar();
return f*x;
}
const int N = 1e5+5;
int n,a[N],L[N/2+2],R[N/2+2];
void mergesort(int l,int r)
{
if(l+1>=r) return ;
int mid=l+r>>1;
mergesort(l,mid); mergesort(mid,r);
int n1=mid-l,n2=r-mid;//n1左边个数,n2右边个数
for(int i=0;i<n1;i++) L[i]=a[l+i];//[l,mid)
for(int i=0;i<n2;i++) R[i]=a[mid+i];//[mid,r)
L[n1]=R[n2]=inf;//哨兵,处理边界
int i=0,j=0;
for(int k=l;k<r;k++)
{
if(L[i]<=R[j]) a[k]=L[i++];
else a[k]=R[j++];
}
}
int main()
{
n=read();
for(int i=0;i<n;i++) a[i]=read();
mergesort(0,n);//[0,n)
for(int i=0;i<n;i++) cout<<a[i]<<" ";
return 0;
}
Clever use of merge sort: Find the number of reversed pairs in the array.
Use the characteristics of merge sort. The numbers in the L array must be on the left side of the original array relative to the R array. Then if the number in R is less than the number in L, the reverse order will occur. Yes, because the L array and the R array itself are ordered, a certain number R[j] in R is less than a certain number L[i] in L, then (L[i],R[j]) is A pair in reverse order. At the same time, the numbers after R[j] and L[i] must also be in reverse order, because L[i]<=L[i+1], and R[j]<L[i], so R [j]<L[i+1]<=L[i+2]…<=L[n1-1] (until the end of the L array)
so the total reverse logarithm generated by R[j] and the L array is n1-i;
#include<cstdio>
#include<cmath>
#include<ctime>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#define ll long long
#define ull unsigned long long
#define up_b upper_bound
#define low_b lower_bound
#define m_p make_pair
#define mem(a) memset(a,0,sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
#include<algorithm>
using namespace std;
inline ll read()
{
ll x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1; ch=getchar(); }
while('0'<=ch&&ch<='9') x=x*10+ch-'0', ch=getchar();
return f*x;
}
const int N = 5e5+5;
int n,a[N],L[N/2+2],R[N/2+2];
ll ans=0;
void mergesort(int l,int r)
{
if(l+1>=r) return ;
int mid=l+r>>1;
mergesort(l,mid); mergesort(mid,r);
int n1=mid-l,n2=r-mid;//n1左边个数,n2右边个数
for(int i=0;i<n1;i++) L[i]=a[l+i];//[l,mid)
for(int i=0;i<n2;i++) R[i]=a[mid+i];//[mid,r)
L[n1]=R[n2]=inf;//哨兵,处理边界
int i=0,j=0;
for(int k=l;k<r;k++)
{
if(L[i]<=R[j]) a[k]=L[i++];
else a[k]=R[j++], ans+=n1-i;
}
}
int main()
{
n=read();
for(int i=0;i<n;i++) a[i]=read();
mergesort(0,n);//[0,n)
// for(int i=0;i<n;i++) cout<<a[i]<<" ";
cout<<ans<<endl;
return 0;
}