time limit per test: 4.0 seconds
time limit all tests: 4.0 seconds
memory limit: 256 megabytes
you want to process a sequence of n
there are several test cases, please process tilleof
.
for each test case, the first line contains integer n
(1≤n≤105
) . the second line contains n
space-separated integers a1,
a2,…
,an (1
≤ai≤
109) .
input
21 2
output
0
題意: 求逆序對。
分析:首先理解歸併排序。 給你乙個混亂的序列,先將它分半變成兩個序列,分別對每個序列排序,然後合併兩個序列。 合併的操作就是每次比較兩個序列的最小值,然後將最小值放到新的序列中,並再原序列刪除那個最小值。
具體操作就是不斷二分,至到每個序列只包含乙個元素,這樣就可以預設當前元素已經排好序了,再進行合併即可。
那怎麼求逆序對呢? 對於每個即將要合併兩個序列,我們可以知道在兩個序列的內部是不存在逆序對的(因為已經是排好序的)。所以逆序對只存在兩個序列之間。舉例來說
假設第乙個序列為 3 4 5 第二個序列為 1 2
那麼對與合併操作,肯定要先比較 3 和 1 的大小,然後將1放到新的序列中。 可以因為3比1大,所以這是乙個逆序對,同樣的,對於第乙個序列中所有大於3的元素,每乙個都可以和1構成逆序對,所以cnt每次要加所有大於等於3的元素的個數。
具體看**。
#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
const int inf = 0x3f3f3f3f;
const int ninf = 0xc0c0c0c0;
const int maxn = 100005;
long long cnt = 0;
void merge_sort(int *a,int *t,int beg,int en)
else t[pos++] = a[s1++];
}while(s1 < e1)
while(s2 < e2)
for(pos = beg;pos> n)
cnt = 0 ;
merge_sort(a,t,0,n);
cout << cnt << endl;
}}
歸併排序求逆序對
排序都用qsort了,別的排序演算法不怎麼用,但有些排序的思想很重要。碰到一道求逆序對的題,要用到歸併排序,學習了一下歸併排序。歸併排序是用分治思想,分治模式在每一層遞迴上有三個步驟 分解 將n個元素分成個含n 2個元素的子串行。解決 用合併排序法對兩個子串行遞迴的排序。合併 合併兩個已排序的子串行...
歸併排序求逆序對
我們知道,求逆序對最典型的方法就是樹狀陣列,但是還有一種方法就是merge sort 即歸併排序。實際上歸併排序的交換次數就是這個陣列的逆序對個數,為什麼呢?我們可以這樣考慮 歸併排序是將數列a l,h 分成兩半a l,mid 和a mid 1,h 分別進行歸併排序,然後再將這兩半合併起來。在合併的...
歸併排序求逆序對
現在給定乙個有n個數的數列ai。若對於i j,有ai aj,則稱 i,j 為數列的乙個逆序對。例如,2,3,8,6,1 有五個逆序對,分別是 1,5 2,5 3,4 3,5 4,5 現在請你求出乙個給定數列的逆序對個數。輸入格式 乙個整數t,表示有多少組測試資料。每組測試資料第一行是乙個正整數n 1...