在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。乙個排列中所有逆序總數叫做這個排列的逆序數。也就是說,對於n個不同的元素,先規定各元素之間有乙個標準次序(這裡規定從小到大為標準次序),於是在這n個元素的任一排列中,當某兩個元素的先後次序與標準次序不同時,就說有1個逆序。乙個排列中所有逆序總數叫做這個排列的逆序數。
而逆序數就是判定乙個排列為奇排列還是偶排列的重點。如果逆序數為奇數,則此排列為奇排列,否則為偶排列。
舉個例子,看53124這個序列,5在3前面,5在1前面,5在2前面,5在4前面,3在1前面,3在2前面,逆序數為6,故此排列為偶排列。
如果直接模擬的話時間複雜度為on^2,但**就簡單的多了,可如果你想優化時間,那麼就得使用到歸併排序了。
注:如果你尚未學習過歸併排序,可以瀏覽此網頁來學習
而逆序數的計算在我們將兩個子串行合併的時候累加就可以了。
舉個例子,如果我們要將這兩個子串行合併的話
1,4,6,7,9
2,3,5,10,13,21
當第乙個序列列舉到第2個元素4,第二個序列列舉到第1個元素2時,4 > 2為逆序,我們需要進行累加,又因為兩個子串行都是有序的所以如果4 > 2,那麼第乙個子串行從第2個元素4開始後面的所有數都必然比2大,所以讓逆序數的值加上(mid - i + 1),既從第2個元素到第5個元素中元素的個數。這樣時間複雜度就減少為on * log2(n)級別的了。
# include
# include
# include
# include
# include
using
namespace std;
# define for(i, a, b) for(int i = a; i <= b; i++)
# define _for(i, a, b) for(int i = a; i >= b; i--)
const
int nr =
100000
;int n, cnt;
int a[nr +10]
;void
mergearray
(int left,
int mid,
int right)
}while
(t1 <= mid) ans[
++len]
= a[t1++];
while
(t2 <= right) ans[
++len]
= a[t2++];
for(i, left, right) a[i]
= ans[i - left +1]
;}void
mergesort
(int left,
int right)
intmain()
排列的逆序數
在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。也就是說,對於n個不同的元素,先規定各元素之間有乙個標準次序 例如n個 不同的自然數,可規定從小到大為標準次序 於是在這n個元素的任一排列中,當某兩個元素的實...
求排列的逆序數
考慮1,2,n n 100000 的排列i1,i2,in,如果其中存在j,k,滿足 j k 且 ij ik,那麼就稱 ij,ik 是這個排列的乙個逆序。乙個排列含有逆序的個數稱為這個排列的逆序數。例如排列 263451 含有8個逆序 2,1 6,3 6,4 6,5 6,1 3,1 4,1 5,1 因...
求排列的逆序數
openjudge011 題目 乙個排列含有逆序的個數稱為這個排列的逆序數。例如排列 263451 含有8個逆序 2,1 6,3 6,4 6,5 6,1 3,1 4,1 5,1 因此該排列的逆序數就是8。顯然,由1,2,n 構成的所有n 個排列中,最小的逆序數是0,對應的排列就是1,2,n 最大的逆...