Study notes: merge and sort

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;
}

Guess you like

Origin blog.csdn.net/m0_50815157/article/details/113422791