區間反轉問題


區間反轉問題

本篇隨筆淺談一下算法競賽中的區間反轉問題。


例題 洛谷 P3391 【模板】文藝平衡樹

題目傳送門

題目描述

您需要寫一種數據結構(可參考題目標題),來維護一個有序數列。

其中需要提供以下操作:翻轉一個區間,例如原有序序列是 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≤lrn


關於區間反轉

對於反轉一段區間的操作,我們好像怎么搞都是\(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,所以直接把每個節點的左右兒子交換就可以。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM