//p1908 逆序對
#includeusing
namespace
std;
int a[500005
];int tmp[500005
];long
long ans=0
;void mergesort(int l,int
r)
while(i<=mid) tmp[++tot]=a[i++];
while(j<=r) tmp[++tot]=a[j++];
for(int i=l;i<=r;i++)
a[i]=tmp[i];
}int
main()
直接暴力求的話,顯然時間複雜度是不可接受的 我們不妨轉換一下,分而治之 把整個數列劈成兩半 則總的逆序對數量=左半部分逆序對數量+右半部分逆序對數量+左邊的數比右邊大的對數 前兩項我們可以遞迴求解,最後一項我們可以在歸併排序的同時稍加處理,o(n)計算出來 這樣時間複雜度與歸併排序一樣,都是o(nlogn)的
歸併排序模板(附求逆序對)
逆序對滿足兩個條件,i j 和 ai aj 歸併可以求逆序對,因為是按順序加入,所以右區間加入的時候,左區間的數滿足 i j,然後左邊還沒有加入的數肯定比當前的a q 要大,應該是按大小加入的,所以滿足ai 所以這個時候計數器可以加上左區間還沒加入數的個數,即 注意是左閉右開區間,所以 不用加一。i...
歸併排序求逆序對
排序都用qsort了,別的排序演算法不怎麼用,但有些排序的思想很重要。碰到一道求逆序對的題,要用到歸併排序,學習了一下歸併排序。歸併排序是用分治思想,分治模式在每一層遞迴上有三個步驟 分解 將n個元素分成個含n 2個元素的子串行。解決 用合併排序法對兩個子串行遞迴的排序。合併 合併兩個已排序的子串行...
歸併排序求逆序對
我們知道,求逆序對最典型的方法就是樹狀陣列,但是還有一種方法就是merge sort 即歸併排序。實際上歸併排序的交換次數就是這個陣列的逆序對個數,為什麼呢?我們可以這樣考慮 歸併排序是將數列a l,h 分成兩半a l,mid 和a mid 1,h 分別進行歸併排序,然後再將這兩半合併起來。在合併的...