首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

POJ 2104 K-th Number 區間第K大 三種解法對比

     編輯:關於C++

問題描述

給定長度 n(≤ 10⁵)的序列,m(≤ 5000)次查詢:區間 [l, r] 中第 k 大的數。無修改操作。

方法一:離線排序 + 枚舉 O(nm)

將原數組值與下標配對排序。每次查詢按值從大到小掃描,計數下標在 [l, r] 的元素,第 k 個即為答案。
雖然理論複雜度高,但 m ≤ 5000,配合 O2 優化常能通過。

方法二:歸並樹 O((n+m) log³ n)

線段樹每個節點存儲該區間已排序的數組。建樹時歸並合併子節點數組。
查詢:二分答案值域,利用 lower_bound 在 log n 層節點上計數 ≤ mid 的個數,總查詢 log³ n。
代碼關鍵:
build 遞歸歸並排序
query(v, L, R) 返回區間 ≤ v 的個數
solve(l, r, k) 二分值域找第 k 大

方法三:分塊樹 / 主席樹 O((n+m) log n)

主席樹(可持久化線段樹)是標準最優解。每個前綴建一棵線段樹,查詢兩棵樹相減得到區間頻率,直接二分樹上找第 k 大。
分塊樹(劃分樹)同樣 O(log n) 查詢,實現較複雜。
本題數據範圍下,歸並樹足夠,主席樹代碼較長此處略過。

複雜度對比

方法預處理單次查詢備註
離線枚舉O(n log n)O(n)代碼最短,實測常通過
歸並樹O(n log n)O(log³ n)平衡選擇
主席樹O(n log n)O(log n)理論最優,代碼長
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved