牛客 逆序數 (歸併排序)

2021-10-09 04:10:16 字數 1267 閱讀 3986

題目描述

在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。比如乙個序列為4 5 1 3 2, 那麼這個序列的逆序數為7,逆序對分別為(4, 1), (4, 3), (4, 2), (5, 1), (5, 3), (5, 2),(3, 2)。

輸入描述:

第一行有乙個整數n(1 <= n <= 100000), 然後第二行跟著n個整數,對於第i個數a[i],(0 <= a[i] <= 100000)。

輸出描述:

輸出這個序列中的逆序數

輸入

54 5 1 3 2輸出7

題目分析

這是乙個經典的歸併排序的模板題,也是乙個樹狀陣列的模板題,但是我不會樹狀陣列!!!,那我們現在來講一下什麼是歸併排序。

ac**

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

100005

;ll a[maxn]

, b[maxn]

, cnt;

void

merge

(ll l, ll mid, ll r)

else

b[t++

]= a[i++];

}//乙個子串行中的數都處理完了,另乙個還沒有,把剩下的直接複製過來

while

(i <= mid)

b[t++

]= a[i++];

while

(j <= r)

b[t++

]= a[j++];

for(

int i = r; i >= l; i--

) a[i]

= b[

--t]

;//把排好序的b陣列複製回a陣列

}void

mergesort

(ll l, ll r)

intmain()

return0;

}

流年似水,有些事一下子過去了,有些事很久也過不去。有些傷痕可以慢慢被修復,而有些傷痕,卻如同釘入木樁中的釘子一般,即使拔出,也烙下深深的印痕,無法忘卻

歸併排序 逆序數

對於數列a,將其二分地拆分為b,c 先將b,c分別排序好,再合併b,c即為總的排序,不過在合併的過程中我們可以算出逆序數哦。其原理網上很多,我這裡不再贅述,只給出實現 include include define ll long long using namespace std ll mergeso...

逆序數(歸併排序)

分而治之 分 每次從中間劃分開,直到有序為止,即乙個整數 void merge int s,int left,int right 治重新定義乙個a陣列,儲存排序完的合併陣列,void sort int s,int left,int mid,int right while i mid a k s i ...

牛客網 逆序對(歸併排序)

思路 我們知道在歸併排序的逆序對求法中,我們是通過遞迴的方式求解每一段的逆序對,通過這個方法我們似乎可以求解該題,在遞迴的過程中,我們多乙個引數用來表示當前遞迴的是第幾層,而這個層數其實就是我們需要找的qi。我們首先預處理出所有層的逆序對數和順序對數,在查詢時我們需要翻轉所有大小為2 qi 的塊,由...