您的位置:首页 > 其它

逆序对解决方法之归并排序

2016-03-24 12:54 225 查看
逆序对即是对于i < j ,ai>aj的(i,j)树对的个数,那么先求出每

个j中i < j ai < aj的i的个数,那么j-i的和即是逆序对总数。

归并排序中 bi ( 0 <= i < n/2) ci(n/2 <= i < n)

则有三种情况:

1,bi中的逆序对数

2,ci中的逆序对数

3,一个在bi,另一个在ci的逆序对数

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

vector<int>v;
//归并排序
ll merge_count(vector<int>& a){
int n=a.size();
if(n<=1) return 0;
ll cnt=0;
//b,c集合分别为a集合的前半部分与后半部分
vector<int> b(a.begin(),a.begin()+n/2);
vector<int> c(a.begin()+n/2,a.end());
cnt+=merge_count(b);//先将b集合排好序
cnt+=merge_count(c);//再将c排好
int ai=0,bi=0,ci=0;
//将b,c合并
while(ai<n){
if(bi<b.size() && (ci==c.size() || b[bi]<c[ci])){
a[ai++]=b[bi++];
}else{
cnt+=n/2-bi;
a[ai++]=c[ci++];
}
}
return cnt;
}

int main()
{
int n;
cin>>n;
int x;
for(int i=0;i<n;i++){
cin>>x;
v.push_back(x);
}
ll ans=merge_count(v);
for(int i=0;i<n;i++){
cout<<v[i]<<" ";
}
cout<<endl;
cout<<ans<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: