本篇隨筆**一下演算法競賽中的區間反轉問題。
題目傳送門
您需要寫一種資料結構(可參考題目標題),來維護乙個有序數列。
其中需要提供以下操作:翻轉乙個區間,例如原有序序列是 5\ 4\ 3\ 2\ 15 4 3 2 1,翻轉區間是 [2,4][2,4] 的話,結果是 5\ 2\ 3\ 4\ 15 2 3 4 1。
第一行兩個正整數 n,mn,m,表示序列長度與操作個數。序列中第 ii 項初始為 ii。
接下來 mm 行,每行兩個正整數 l,rl,r,表示翻轉的區間。
輸出一行 nn 個正整數,表示原始序列經過 mm 次變換後的結果。
【資料範圍】
對於 100%100% 的資料,1 \le n, m \leq 1000001≤n,m≤100000,1 \le l \le r \le n1≤l≤r≤n。
對於反轉一段區間的操作,我們好像怎麼搞都是\(o(n)\)的。
然而對於這道題來講,\(o(n)\)演算法肯定是過不去的。
想要用更優秀的複雜度來做,怎麼辦呢?
用平衡樹來公升級,而且必須用splay。
複雜度達到了均攤\(o(\log n)\)(證明別找我)。
這就已經很優秀了。
那麼為什麼平衡樹的splay演算法能夠用均攤\(o(\log n)\)的複雜度來實現區間反轉呢?
現在我們用節點編號來建一棵bst。那麼根據bst的性質,對於乙個針對區間\([l,r]\)的反轉操作,我們肯定需要把這個區間變到乙個可以方便操作的位置。
那麼我們考慮把節點\(l-1\)用旋轉splay到根節點,把節點\(r+1\)用旋轉splay到根節點的右兒子,根據bst性質,因為我們是使用節點編號建的bst,那麼我們就發現:右兒子的左子樹就是我們需要操作的區間。這個區間已經被唯一確定下來了。
然後因為我們是用節點編號建的bst,所以直接把每個節點的左右兒子交換就可以。
區間問題 區間選點 區間問題 貪心
玄學的貪心問題,一般全憑直覺。貪心問題沒有固定討論,沒有模板,見多了就好了,證明想法的正確性是很困難的,大多採用反證法。905.區間選點 貪心思路 證明 時間複雜度 o n logn o nlogn o nlog n include include using namespace std const...
演算法 鍊錶反轉和鍊錶內指定區間反轉
鍊錶反轉 輸入乙個鍊錶,反轉鍊錶後,輸出新鍊錶的表頭。例如 輸入,返回。public listnode reverse listnode head return temp 鍊錶內指定區間反轉 將乙個鍊錶 m 位置到 n 位置之間的區間反轉,要求時間複雜度o n 空間複雜度o 1 例如 給出的鍊錶為 ...
反轉(開關問題)
poj3276 n頭牛排成一列,牛頭向前或向後。擁有一台自動轉向機器,設定數值k,每次使用可以令k頭連續的牛轉向。求為了讓所有的牛都面向前方需要的最少操作次數m和對應最小的k。首先交換區間順序對結果是沒有影響的,此外對同乙個區間進行兩次以上反轉是多餘的。因此,問題轉化成了求需要被反轉的區間的集合。於...