資料結構的非經典解法

2021-08-09 13:01:06 字數 1958 閱讀 9379

把要維護的序列分成⌈n

√⌉塊, 每塊長度⌊n

√⌋ (

最後一塊的長度為n−

⌊n√⌋

2 )

對於單次區間操作:

被該區間包含的整塊打上標記, 左端和右端剩餘部分(小於2n

√ 個)直接暴力操作, 複雜度為o(

n√)

**:分塊

2.莫隊(離線)

對於一系列區間操作:

假設我們在已知區間[l

,r] 的答案, 在o(

f(n)

) 的時間複雜度內能夠得到[l

−1,r

],[l

+1,r

],[l

,r−1

],[l

,r+1

] 的答案, 按照一定的順序將操作排序, 使得在相鄰的兩次操作區間進行上述轉移的複雜度為g(

n), 通過暴力轉移來進行操作, 時間複雜度為o(

f(n)

⋅g(n

))

經典排序方法

我們利用上面的分塊演算法將序列分為⌈n

√⌉塊, 當2個詢問區間的左端點在同一塊時, 按照右端點來排序, 否則按照左端點來排序, 不難證明完成全部轉移的複雜度為o(

nn√)

**:莫隊

3.cdq分治(離線)

對於多維偏序問題:

這裡討論最簡單的3維偏序問題: 在三維座標中乙個點有3個屬性x,

y,z , 定義點(x

i,yi

,zi)

小於另外乙個點(x

j,yj

,zj)

當且僅當xi

≤xj 且yi

≤yj 且zi

≤zj , 對於每乙個點回答比該點小的點的個數

先對第一維

x 進行公升序排序, 並對點編號, 對於編號在[l

,r]的所有點, 我們取mi

d=l+

r2, 這時編號在[l

,mid

] 的點的

x 座標一定小於或等於[m

id+1

,r]的點, 接下來分別對編號為[l

,mid

] 和[m

id+1

,r] 的點對第二維

y 進行公升序排序, 對於在[m

id+1

,r]裡面的每乙個點pi

, 我們將[l

,mid

] 區間中

y 座標小於或等於pi

的z座標更新進某種資料結構(用於查詢字首和), 通過一次查詢點pi

的z座標的字首和, 便能夠得到編號在[l

,mid

]區間中比pi

點小的點的個數, 再遞迴處理[l

,mid

] , [m

id+1

,r] ,複雜度o(

nlog

2n)

**:cdq分治

4.整體二分(離線)

對於一些列區間詢問:

考慮單個詢問區間為[l

,r] 的詢問: 如果該詢問能夠在不改變原序列複雜度只和該區間的長度線性相關, 那麼就可以使用整體二分來解決所有的詢問

對於答案區間[l

,r] , 我們取中點mi

d=l+

r2, 如果該詢問的答案小於或等於mi

d 那麼將該詢問劃分到左區間, 否則劃分到右區間, 遞迴處理左區間和右區間, 複雜度o(

nlog

n)

**:整體二分

經典的資料結構 佇列

超級經典的資料結構,如下 testconsole.cpp 定義控制台應用程式的入口點。include stdafx.h include include using namespace std struct node struct queue 初始化鏈隊 void initqueue struct q...

資料結構經典演算法

例如 4和3只出現過一次,請找出出現過一次的數。首先想到的 應該是上乙個提到的遍歷兩次取出沒有找到的相同的數字,如下 public static list findonlynum int array if j array.length if array i array j if j array.le...

資料結構 馬走日的解法

假設西洋棋棋盤有5 5共25個格仔。設計乙個程式,使棋子從初始位置 如圖 開始跳馬,需要將棋盤的格仔全部都走一遍,每個格仔只允許走一次。p.s西洋棋的棋子是在格仔中間的。西洋棋中的 馬走日 如第一步為 1,1 第二步為 2,8 或 2,12 第三步可以是 3,5 或 3,21 等,以此類推。incl...