題目描述
在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。比如乙個序列為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 的塊,由...