這是學完鄧公的資料結構第二章向量(vector)之後的problem assignment,直接貼出題目的text:
描述
數軸上有n個點,對於任一閉區間 [a, b],試計算落在其內的點數。
輸入
第一行包括兩個整數:點的總數n,查詢的次數m。
第二行包含n個數,為各個點的座標。
以下m行,各包含兩個整數:查詢區間的左、右邊界a和b。
輸出
對每次查詢,輸出落在閉區間[a, b]內點的個數。
樣例
輸入
5 2
1 3 7 9 11
4 67 12
輸出
0
3
限制
0 ≤ n, m ≤ 5×10^5
對於每次查詢的區間[a, b],都有a ≤ b
各點的座標互異
各點的座標、查詢區間的邊界a、b,均為不超過10^7的非負整數
記憶體:256 mb
思路比較簡單,大體上就是先對輸入的整一組點進行排序,隨後對其進行查詢,找到給定區間的左端點和右端點,然後計算落在其中的元素的數目。
有幾個細節需要注意一下,這道題的排序如果採用類似二路歸併排序這種複雜度為o(nlogn) 的排序演算法,最後幾個測試案例是要tle(超時)的,所以這邊我採用的是計數排序(複雜度為o(n),只要一趟迴圈就可以了),多開乙個規模和輸入規模相當的陣列,用空間換時間;第二個要注意的是,如果這邊採用的查詢是鄧俊輝的資料結構中採用的,即「返回乙個不大於查詢值的且在向量中秩最大的元素的位置」(白話就是待查詢元素唯一時返回那個唯一的,待查詢元素不唯一是返回最前面的,待查到元素找不到時返回小於它的最大元素)的話,要特判待查詢元素小於陣列最小元素的情形,因為這時候返回的秩是-1。
下面貼出完整版的ac**:
#include
#define counting_sort_array_capacity 10000001
class
vector
~vector()
intsize
(void
)int
&operator
(int _rank)
void
sort
(void
)//通過犧牲空間換取時間,將向量元素的值對映到count陣列的下標,下標對應的值記錄出現次數
for(
int i =
0; i < m_size; i++
)//對映
int k =0;
for(
int i =
0; i < counting_sort_array_capacity; i++
)//排序/
}delete
count_array;}}
intsearch
(const
int& _ele,
int _low,
int _high)
const
//採用二分查詢的方式,返回不大於_ele的最大元素的下標
else
}return
--_low;
}protected
:bool
ordered
(void
)const
//按公升序排序的方法,判斷當前向量中是否存在逆序對,元素需支援比較大小或者過載比較運算子
}return ordered;
}private
:int
* m_elements;
int m_size;};
typedef
struct closedinterval //存輸入的待查詢的閉區間
closedinterval;
intmain()
closedinterval* range =
new closedinterval[m]
;for
(int i =
0; i < m; i++);
}//演算法部分
v.sort()
;//先對v排序
//二分查詢區間端點的在陣列中的位置,相減得到元素個數
for(
int i =
0; i < m; i++
)else
}delete
range;
return0;
}
report CST資料結構(2022春)PA1
cst 1 1 a b problema.使用了基礎的資料結構 陣列,採用高精度演算法,原理為模擬乘法豎式進行運算,有採用壓位 b.i 壓位用int壓5位發現運算過程出現上溢,後改為用long long壓8位.ii 忽視了兩數相乘後位數可能會超出上限,後將陣列容量擴大一倍.iii 未考慮到乘0會導致...
資料結構 01
輸入一顆二元樹,從上往下按層列印樹的每個結點,同一層中按照從左往右的順序列印。例如輸入 演算法流程 個人演算法思想 定義乙個佇列 queue 1.根節點先入佇列 2.拿出佇列中第乙個元素尋找其左右孩子 3.如果有入隊,再拿下乙個,直到拿完第乙個孩子入隊之前的所有元素,並以此進行迴圈直至佇列中元素為空...
暑假 實用資料結構 動態範圍查詢問題
動態範圍查詢問題 一 線段樹 點修改 支援操作 update x,v 將ax修改為v query l,r 計算 l,r 內的最小值 1 intminv maxn 2int ql,qr 3int query int u,int l,int r 10 11int p,v a p v 12void upd...