求逆序數兩種方法 線段樹 歸併排序

2021-08-04 02:36:10 字數 2159 閱讀 5734

題目:hdu 4911/poj 2299

第一反應是暴力掃一遍,時間複雜度o(n^2),這在處理10^5的數量級的資料時一定會超時。以下給出兩種將時間複雜度優化至o(nlogn)的方法

以hdu 4911為例,求逆序數的模板題

方法1,歸併排序法:

在區間[l,r]上,mid=(l+r)>>1;

將兩串已經排好序的序列a[l...m]與a[m+1...r]進行歸併排序。設l<=i<=mid當a[j]>=a[i]時,後面的數大於前面的數,不產生逆序對,直接進行歸併即可(tmp[k++]=a[i++]),當a[i]>a[j]時,表示前面的數大於後面的數,產生了逆序對。此時i~m的數均比a[j]大,即,產生m-i+1個逆序對。故逆序對總數應加上(m-i+1)

**:

//by sean chen

#include #include #include #include #include using namespace std;

int n,k;

long long cnt;

int a[100005],tmp[100005];

void merge(int head, int mid, int tail) //二路歸併

else //後面的數大於前面的數,直接將前面的數加入歸併後的序列

}while (i <= mid)

while (j <= tail)

for (int i = head; i <= tail; i++)

return;

}void merge_sort(int head, int tail)

return;

}int main()

cnt = 0;

merge_sort(0, n-1);

if (cnt <= k)

cout << 0 << endl;

else

cout << cnt-k << endl;

}return 0;

}

方法二:線段樹+離散化

通過線段樹,不斷統計當前數字之前比其大的數字的個數,並將當前數字加入線段樹,直至最後乙個即可。方法較為容易理解,在暴力的基礎上,對統計個數的方法進行了優化。注意,由於數字大小到達了10^9,所以需要進行離散化。

//by sean chen

#include #include #include #include #include using namespace std;

const int maxn = 500500;

int n, a, b, in[maxn], tt[maxn], tmp[maxn], f[maxn], k, q;

long long num[maxn*3];

int bs(int v, int x, int y) //二分查詢當前的數字的編號

return x;

}void build(int pos, int l, int r)

void update(int pos, int l, int r)

int m = (l+r) >> 1;

if(a <= m)

update(pos<<1, l, m);

else

update(pos<<1|1, m+1, r);

num[pos] = num[pos<<1] + num[pos<<1|1];

}long long query(int pos, int l, int r)

int main()

sort(in, in+n);

k = 0;

tmp[k++] = in[0];

for(int i = 1; i < n; i++) //離散化

if(in[i] != in[i-1])

tmp[k++] = in[i];

for(int i = 0; i < n; i++)

long long ans = 0;

build(1, 0, k-1);

for(int i = 0; i < n; i++) //逐個統計之前比他大的數並加入線段樹

if (ans > q)

cout << ans-q << endl;

else

cout<< 0 <

**:

求逆序數 逆序數 歸併排序

求排列的逆序數 分治 一 題目描述 總時間限制 1000ms 記憶體限制 65536kb 描述 在internet上的搜尋引擎經常需要對資訊進行比較,比如可以通過某個人對一些事物的排名來估計他 或她 對各種不同資訊的興趣,從而實現個性化的服務。對於不同的排名結果可以用逆序來評價它們之間的差異。考慮1...

歸併排序 求逆序數

首先需要了解逆序對的概念 如果在乙個序列 數列中,滿足 則ax和ay稱為一對逆序對。現在考慮乙個問題 對乙個大小為n 即有n個元素 元素隨機無序且唯一的整數序列中,平均有多少個逆序對?乙個構造證明的方法如下 設乙個隨機無序且元素唯一的整數序列為 我們令lr為l的反向序列,即 然後在lr中任取兩個數,...

歸併排序求逆序數

輸入 n 陣列中元素個數 x 最後所存在的每對逆序對所需要花費的錢 y 按任意順序交換陣列中相鄰兩個元素所要花費的錢 n個陣列中元素 輸出 求使陣列變為公升序所需要的最少 即求該陣列的逆序數 按陣列順序 任意順序交換次數均為該陣列的逆序數次 歸併排序求逆序數 歸併排序採用分治策略 ex 重點在於合併...