題目: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 重點在於合併...