acwing788,求逆序对的数量,归并思想

如果暴力时间复杂度是o(N2)
用归并,我们可以把数组一分为二,左边和右边的逆序对数量相加在加上横跨左右两边逆序对数量
(*截图来源于acwing基础算法课)
因为i是第一个大于j 的位置且上数组已经排序好,所以i后面的数都大于j
此方法相对于暴力来说每次只要找到第一个比j的数就可以确定后面数对
#include <iostream>

using namespace std;

int n;
const int N=100005;
int  a[N],tem[N];

long long mergeSort(int a[],int l,int r){//用递归的板子解决逆序对数量 ;操作的数组,左,右 
	if(l>=r) return 0;//当区域只有一个或空时没有逆序对 
	
	long long res=0;
	int mid=l+r>>1, i=l, j=mid+1, k=0;
	res=mergeSort(a,l,mid)+mergeSort(a,mid+1,r);//先把左右区域的逆序对数量加上 
	//以下基本为归并的板子 
	while(i<=mid&&j<=r){//当i j一个达到终点时跳出 
		if(a[i]<=a[j]) tem[k++]=a[i++];
		else{
			res+=mid-i+1;
			tem[k++]=a[j++];//逆序对增加的操作,上的第一个i比j大,那么i之后的都比j大 
		}
	}
	//把另一组还未加的归并掉 
	while(i<=mid) tem[k++]=a[i++];
	while(j<=r) tem[k++]=a[j++];
	//物归原主,tem转进a 
	for(int i=l,j=0;i<=r;i++,j++) a[i]=tem[j];
	return res;
}

int main(int argc, char** argv) {
	cin>>n;
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	cout<<mergeSort(a,0,n-1)<<endl;
	return 0;
}

统计数组内满足两两大小关系的问题可以用归并的思想

全部评论

相关推荐

HR_丸山彩同学:你的项目描述里,系统设计讲了很多:MemCube是什么、三级存储架构怎么设计、四种遗忘策略分别是什么。这些面试的时候讲没问题,但简历上不需要这么细。 简历要突出的是影响力,不是实现细节。面试官看简历的时候想知道的是「这个项目有多大价值」,不是「这个项目具体怎么实现的」。实现细节是面试时候聊的 怎么改:技术细节可以精简为一句「采用三级存储架构+四种遗忘策略」,把省出来的篇幅用来写影响力。比如:项目有没有开源?有没有写成技术博客?有没有被别人使用过? 校园经历没有任何信息量,任何人都可以写这句话,写了等于没写。更关键的是,你投的是技术岗,校园活动经历本来就不是加分项。如果非要写,必须写出具体的数字和成果。如果你没有这些数字,那就老老实实删掉 「端到端耗时缩减30-40%」要给出确切数字和绝对值。从1000ms降到600ms是降了40%,从100ms降到60ms也是降了40%,但这两个含义完全不一样。其他也是,涉及到数据,准备好证据,口径统一,面试会问 「熟练」「熟悉」「了解」混在一起用,读起来很乱。而且「了解前端需求」最好改成「具备前后端协作经验」
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务