zoukankan      html  css  js  c++  java
  • 归并排序求 逆序对

    #include<iostream>
    using namespace std;
    const int N=500010;
    typedef long long ll;
    ll cnt;//记录逆序对的数量
    int n,a[N],num[N];//num 归并的辅助数组
    #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    
    void sort(int l,int r,int *a)
    {
    	if(l>=r) return ;
    	int mid= l+r >> 1;
    	sort(l,mid,a);
    	sort(mid+1,r,a);
    	int pl=l,pr=mid+1,temp=l;
    	while(pl<=mid&&pr<=r)//只用求分别位于两部分的逆序对即可,两部分之内的递归已经求过了
    	{
    		if(a[pl]<=a[pr]) num[temp++]=a[pl++];
    		else num[temp++]=a[pr++],cnt+=mid-pl+1;//pl指向的数比pr大,而且pl到mid是增序的所以pl到mid的所有都比pr大且是逆序对 
    	}
    	while(pr<=r) num[temp++]=a[pr++];//两半部分可能没有扫完,且最多只有一个部分,所以都while一下可以少判断一下,最多只会执行一次
    	while(pl<=mid) num[temp++]=a[pl++];
    	
    	for(int i=l;i<=r;i++) a[i]=num[i];//将排好序的数组填回原数组
    	return ;
    }
    int main()
    {
    	IOS;
    	cin>>n;
    	for(int i=0;i<n;i++) cin>>a[i];
    	sort(0,n-1,a);
    	cout<<cnt;
    	return 0;
     } 
    
  • 相关阅读:
    解释器模式
    命令模式
    责任链模式
    代理模式
    享元模式
    外观模式
    装饰器模式
    组合模式
    过滤器模式
    js广告浮动
  • 原文地址:https://www.cnblogs.com/neflibata/p/12871776.html
Copyright © 2011-2022 走看看