題目鏈結
看到這個資料量,你就不應該想著去寫個暴力。
我原來已經寫過一遍這個題目了,並且還記得是歸併排序來做,但是有點記不得是怎麼推導出思路的了,因此決定重新推導一遍。我找到了原來的ppt,並且加一點自己的理解吧。
一開始的時候應該是1)+2),但是1)被分解成更小的1)和更小的2)。當只有兩個數的時候,就只有2)沒有1)了
下面的是一開始自己的想法,但是有點亂了。
假設有乙個陣列a1
,a2,
⋯,am
,am+
1,am
+2,⋯
,an ,此時按照中間分成a1
,a2,
⋯,am
和am+
1,am
+2,⋯
,an 。那麼我們計算總逆序對對數,就只需要計算從1到m的逆序對數,從m+1到n的逆序對數,以及左邊與右邊的逆序對數。對於求從1到m的逆序對數,以及m+1到n的逆序對數,顯然從形式上就知道應該是遞迴。對於左邊和右邊的逆序對數,考慮到交換左邊任意兩個數的位置,不會影響到左邊到右邊的逆序對對數,因此左邊的數可以任意交換位置。同理,右邊的也可以任意交換。
不過我想了想,好像上面這種思路對於遞迴的時候來說,有點難以接受,我決定換一種思路來考慮。實際上,如果你用暴力o(
n2) 求出所有的逆序對的時候,你會發現這些逆序對就是氣泡排序中出現的交換次數。我在想證明的時候找到了這麼一篇文章。我們有逆序對數等於氣泡排序交換次數。後來我想想這段我好像沒有發現什麼有用的結論。。。
#include
using
namespace
std;
const
int maxn = 1000005;
long
long a[maxn];
long
long t[maxn];
void merge_sort_and_count(long
long a, int s, int e, long
long t);
void merge(long
long a, int s, int m, int e, long
long t);
long
long count = 0;
int main()
merge_sort_and_count(a, 0, n - 1, t);
cout
<< count << endl;
}return
0;}
void merge_sort_and_count(long
long a, int s, int e, long
long t)
int m = s + (e - s) / 2;
merge_sort_and_count(a, s, m, t);
merge_sort_and_count(a, m + 1, e, t);
merge(a, s, m, e, t);
}void merge(long
long a, int s, int m, int e, long
long t) else
}while(pa <= m)
while(pb <= e)
for(int i = 0; i < pt; i++)
}
普及練習場 分治演算法 P1010 冪次方
題目描述 任何乙個正整數都可以用 2 的冪次方表示。例如 137 27 23 2 0 同時約定方次用括號來表示,即 a b 可表示為 a b 由此可知,137 可表示為 2 7 2 3 2 0 進一步 7 22 2 20 2 1用2表示 並且 3 2 2 0 所以最後 137 可表示為 2 2 2 ...
普及練習場之排序
題目提供者ccf noi 評測方式雲端評測標籤noip普及組2006 難度入門難度 時空限制1000ms 128mb 提交 題解 明明想在學校中請一些同學一起做一項問卷調查,為了實驗的客觀性,他先用計算機生成了nn個11到10001000之間的隨機整數 n 100 n 100 對於其中重複的數字,只...
普及練習場之排序
p1177 模板 快速排序 總 看題目,模板啊!var n,i longint a array 1.100001 of longint procedure qsort l,r longint var i,j,temp,key longint begin if l r then exit i l j ...