逆序數介紹以及演算法實現

2021-09-10 23:22:33 字數 2501 閱讀 8117

對於逆序數通俗的理解:對於序列中每個位置的的數,其之前比他的值大的個數之和,或者在其之後比他的值小的個數之和,如此稱為逆序數

實現手段:線段樹、樹狀陣列、離散化、歸併排序、列舉

int ans =0;

//逆序數個數

int num[maxn]

;for

(int i =

1; i < n; i++)}

}

#include

using

namespace std;

int a[

100005];

//儲存有多少比它大的數字在它之前

intmain()

} cout << sum << endl;

}

細節

關於sum的含義是求得1~idx下標得字首和,在這裡根據方法2得思路就是rank <= idx的字首數量,這裡就要利用到一點容斥的思想:我們的目標是考慮當前有多少個比當前數排名大的數,當前全集為i,rank <= idx的數量為sum(idx),則當前 rank > idx 的數量為i-sum(idx)。其實c維護的就是rank的數量。舉例:

目前資料集

目前下標得到的逆序數

說明初始化

逆序數為0,資料集為空

0加入7,排名為4,逆序數為0,前面沒有排名比他高的數字

1加入4,排名為2,逆序數為1,前面排名有1個比他高的數字,分別為7

2加入3,排名為1,逆序數為2,前面排名有2個比他高的數字,分別為7,4

0加入8,排名為5,逆序數為0,前面排名有0個比他高的數字

2加入6,排名為3,逆序數為2,前面排名有2個比他高的數字,分別為7,8

觀察c陣列的變化

("\n\n排列的逆序數為 = %lld\n"

,sum);}

return0;

}

#include

#include

using

namespace std;

const

int maxn =

(int

)1e5+5

;typedef

long

long ll;

typedef

double db;

typedef

long

double ldb;

int val[maxn]

,tmp[maxn]

;ll cnt;

void merge (

int l,

int m,

int r)

else

}while

(i <= m)

while

(j <= r)

for(

int i = l; i <= r; i++)}

void

mergesort

(int l,

int r)

return;}

intmain()

cnt =0;

mergesort(1

, n)

; cout << cnt <<

'\n'

;return0;

}

分治遞迴逆序數 逆序數的分治演算法

給我們乙個序列,讓我們求其逆序數 如3 2 1 4 逆序數為 2 1 0 0 3 我們這樣定義乙個序列的逆序數 序列a1 a2 a3 a2 an 這個序列的逆序數c,等於a1,a2.的逆序數的和.即 c sum ci ci為滿足ai aj j i 的數的總的個數,即ci sum ai aj j i ...

分治遞迴逆序數 歸併演算法經典應用 求解逆序數

原創不易,求個關注 在之前介紹線性代數行列式計算公式的時候,我們曾經介紹過逆序數 我們在列舉出行列式的每一項之後,需要通過逆序數來確定這一項符號的正負性。如果有忘記的同學可以回到之前的文章當中複習一下 線性代數精華1 從行列式開始 如果忘記呢,問題也不大,這個概念比較簡單,我想大家很快就能都搞清楚。...

求逆序數的分治演算法

給我們乙個序列,讓我們求其逆序數 如3 2 1 4 逆序數為 2 1 0 0 3 我們這樣定義乙個序列的逆序數 序列a1 a2 a3 a2 an 這個序列的逆序數c,等於a1,a2.的逆序數的和.即 c sum ci ci為滿足ai aj j i 的數的總的個數,即ci sum ai aj j i ...