逆序對解決方法之歸併排序

逆序對即是對於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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章