【模板】归并排序(逆序对)

归并排序模板

#include<bits/stdc++.h>
using namespace std;
int a[100005];
void merge(int l,int r){
	int mid=(l+r)/2;
	int aux[r-l+1];
	for(int i=l;i<=r;i++){
		aux[i-l]=a[i];
	}//第一步:复制该数组[l,r]部分 
	int i1=l,i2=mid+1;//第二步:双指针 
	for(int i=l;i<=r;i++){//第三步:如果其中一半的指针已经到头,就直接加入另一半;否则,就对两指针指向的元素进行比较 
		if(i1>mid){
			a[i]=aux[i2-l];
			i2++;
		}else if(i2>r){
			a[i]=aux[i1-l];
			i1++;
		}else if(aux[i1-l]>aux[i2-l]){
			a[i]=aux[i2-l];
			i2++;
		}else{
			a[i]=aux[i1-l];
			i1++;
		}
	}
}
void mergesort(int l,int r){//分治:先分后合的递归 
	if(l>=r) return;//注意跳出条件:l>=r 
	int t=(l+r)/2;
	mergesort(l,t);
	mergesort(t+1,r);
	merge(l,r);
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	mergesort(0,n-1);
	for(int i=0;i<n;i++) cout<<a[i]<<' ';
}

例子:逆序对

	for(int i=l;i<=r;i++){//第三步:如果其中一半的指针已经到头,就直接加入另一半;否则,就对两指针指向的元素进行比较 
		if(i1>mid){
			a[i]=aux[i2-l];
			i2++;
		}else if(i2>r){
			a[i]=aux[i1-l];
			i1++;
			ans+=i2-mid-1;
		}else if(aux[i1-l]>aux[i2-l]){//取等号错:只有i2严格小于i1时,进i2,保证i1前面的i2都是严格小于它的 
			a[i]=aux[i2-l];
			i2++;
		}else{
			a[i]=aux[i1-l];
			i1++;
			ans+=i2-mid-1;
		}
	}//当插入i1(左半边指针时)加上左边插入过的,右半边元素的个数。 
//之所以能够这样算,是因为归并排序保证了每半边的有序性。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值