poj 2299(逆序對(樹狀陣列 歸併排序))

2021-08-06 03:09:05 字數 2355 閱讀 2636

題目鏈結

題目大意:

在這個問題中,你必須分析乙個特定的排序演算法。 該演算法通過交換兩個相鄰的序列元素來處理n個不同整數的序列,直到序列按公升序排序。 對於輸入序列

9 1 0 5 4,

通過ultra-quicksort輸出

0 1 4 5 9。

你的任務是確定ultra-quicksort需要執行多少交換操作才能排序給定的輸入序列。

輸入 該輸入包含幾個測試用例。 每個測試用例從一行包含單個整數n <500,000 - 輸入序列的長度開始。 以下n行中的每一行包含第i個輸入序列元素的單個整數0≤a[i]≤999,999,999。 輸入由長度為n = 0的序列終止。該序列不能被處理。

輸出 對於每個輸入序列,您的程式將列印一行包含乙個整數op,乙個排序給定輸入序列所需的最小交換運算元。

樣例輸入

5 9

1 0

5 4

3 1

2 3

0樣例輸出 6 0

參考部落格

解法一:樹狀陣列

由於題目資料過大,顯然考慮離散化

然後用樹狀陣列維護

可以將原陣列位置與排序後的位置對應

以排序後陣列建樹狀陣列,

如果第i位有乙個數

void update(int i)

}

對於每個數,我們搜它前面比它小的數的個數

再用它原陣列位置減去即是包含這個數的逆序對個數

具體看**

#include

#define ll long long

#define max 2147483647

#define fi first

#define se second

#define mid (l+r>>1)

#define fo(i,a,b) for(int i=(a);i<=(b);++i)

#define fodown(i,a,b) for(int i=(a);i>=(b);i--)

using namespace std;

int n;

struct nodea[500001];

int ch[500001];

int c[500005];

ll ans=0;

int read()

while(ch>='0'&& ch<='9')

return x*tmp;

}bool cmp(node a,node b)

void update(int x)//在x位置上有乙個數

}int getsum(int x)

return sum;

}int main()

sort(a+1,a+n+1,cmp);

fo(i,1,n)

ch[a[i].rank]=i;

memset(c,0,sizeof(c));

ans=0;

fo(i,1,n)

cout0;}

解法二:歸併排序

顯然,對於本題樹狀陣列過於高大上了,資料範圍大,難求字首和,一定要離散化,複雜度應該比歸併略高

如何想到歸併?

題目要你想乙個演算法,求出將原陣列排序後交換的次數

首先想到氣泡排序,但代價太高

快排又不行

o(nlog(n))演算法只有歸併可行(歸併我只會求逆序對)

具體看**

#include

#include

#include

#define ll long long

#define max 2147483647

#define fi first

#define se second

#define fo(i,a,b) for(int i=(a);i<=(b);++i)

#define fodown(i,a,b) for(int i=(a);i>=(b);i--)

using

namespace

std;

int n,a[500005],b[5000005];

ll ans;

int read()

while(ch>='0'&& ch<='9')

return x*tmp;

}void merge(int l,int m,int r)

}while(i<=m)

while(j<=r)

fo(t,l,r)

a[t]=b[t];

} void qsort(int l,int r)

int main()

poj 2299 樹狀陣列

題目大意 本題要用到樹狀陣列的離散化處理,因為資料太大 1 999999999 但還是wa了兩次,c i 的範圍計算錯誤,要用到long long 從後向前處理,每次處理乙個數,求比這個數小的個數。poj 2299 樹狀陣列 include include include include inclu...

樹狀陣列求逆序對 離散化 poj2299

今天做了乙個樹狀陣列求逆序對的題,需要離散化,看了部落格明白了為什麼要進行離散化,原因是樹狀陣列中的c maxn 陣列其實相當於乙個雜湊操作,如果所給陣列中存在值特別大的元素,陣列就需要離散化 include include include include using namespace std s...

樹狀陣列求逆序數 poj 2299

突然想起樹狀陣列了,因為突然想起之前從來沒a掉的那個樹狀陣列求逆序數的題,大概意思就是求乙個陣列用氣泡排序排序後的交換次數,因為資料量為5萬,所以o n n 的冒泡模擬肯定是超時的,所以題目的解法可以有兩種,一種是歸併排序,歸併排序的乙個應用正是求逆序數,而另乙個就是樹狀陣列了。思想就是通過將數乙個...