真正的模板題,先用splay把這個題打熟了再來做這個題qwq
splay的基本操作我就不講了,直接說一說這個題的做法
首先我們把序列放到一棵樹上,使得這棵樹的中序遍歷為原序列,這個建樹操作和線段樹類似,遞迴建立左右兒子,然後進行兩個操作
f in
dfind
find
:獲取序列第x
xx位置上的值
r ev
erse
reverse
revers
e:反轉乙個區間
對於乙個區間,我們將它翻轉,我們進行這樣的操作:設要翻轉的區間為(l,r)
(l,r)
(l,r
),先把l−1
l-1l−
1這個點splay到根,然後把r+1
r+1r+
1這個點splay到l−1
l-1l−
1這個點的左兒子,這時r+1
r+1r+
1的右子樹就是(l,
r)
(l,r)
(l,r
)區間了,我們把r+1
r+1r+
1的右兒子的子樹內所有點的左右子樹交換即可
直接暴力交換可不行,思路同線段樹,我們可以為乙個點打上標記,等要訪問這個點的兒子的時候交換左右兒子並下放標記即可這樣的做法在我們翻轉[1,n]區間的時候比較難受,所以我們可以在頭尾建立乙個虛點
#include
#include
#include
#include
#include
#include
#define ls son[now][0]
#define rs son[now][1]
using
namespace std;
void
file()
const
int n=
500010
;inline
intread()
int n,m,rt;
int tag[n]
,son[n][2
],siz[n]
,fa[n]
;bool
l_r(
int x)
void
pushup
(int now)
void
pushdown
(int now)
void
build
(int last,
int l,
int r)
void
rotate
(int x,
int&goal)
void
splay
(int x,
int&goal)
}int
find
(int x)}}
void
reverse
(int l,
int r)
intmain()
for(
int i=
2;i<=n+
1;i++
)printf
("%d "
,find
(i)-1)
;return0;
}
洛谷 P3391 模板 文藝平衡樹
這是一道經典的splay模板題 文藝平衡樹。您需要寫一種資料結構,來維護乙個有序數列,其中需要提供以下操作 翻轉乙個區間,例如原有序序列是5 4 3 2 1,翻轉區間是 2,4 的話,結果是5 2 3 4 1 輸入格式 第一行為n,m n,m 100000 n表示初始序列有n個數,這個序列依次是 1...
洛谷P3391 模板 文藝平衡樹
您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列。其中需要提供以下操作 翻轉乙個區間,例如原有序序列是 5 4 3 2 1 翻轉區間是 2,4 的話,結果是 5 2 3 4 1 splay 模板。總算是會摳 splay 了。treap 採用鍵值隨機化來維護 bst 平衡,而 splay 則採...
洛谷 P3391 模板 文藝平衡樹(Splay)
這是一道經典的splay模板題 文藝平衡樹。您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 翻轉乙個區間,例如原有序序列是5 4 3 2 1,翻轉區間是 2,4 的話,結果是5 2 3 4 1 輸入格式 第一行為n,m n表示初始序列有n個數,這個序列依次是 1,2,...