傳送門
splay模板題
考慮如何把一顆樹翻轉
把它的左右兒子翻轉,左右兒子的左右兒子翻轉...直到每個節點都被翻轉
一顆樹這樣轉後可以發現樹的中序遍歷也剛好左右翻轉了
所以可以用splay維護,維護標記也不難,只要每次向下之前都先傳一下標記就可以了
注意此時splay節點的大小關係是他們在序列的位置而不是值
至於提取區間的操作就只要把 l-1 號節點搞到根,把 r+1 號節點搞到根的右兒子
那麼整個 l~r 的區間就在 r+1 號節點的左兒子上了
一開始建樹可以直接建乙個完美的平衡樹
因為可能會訪問到0號節點或n+1號節點,所以要增加兩個虛節點防止越界
#include#include#include
#include
#include
using
namespace
std;
const
int n=1e5+7
;inline
intread()
while(ch>='
0'&&ch<='9'
)
return x*f;
}int
n,m;
int ch[n<<2][2],val[n<<2],fa[n<<2],sz[n<<2
],rt;
bool rev[n<<2];//
翻轉標記
inline void pushdown(int &x)//
下傳標記
if(r)
rev[x]=0
; }
}inline
void pushup(int &x) //
更新節點
inline void rotate(int x,int &k)//
伸展inline
void splay(int x,int &k)
rotate(x,k);
}}void build(int l,int r,int f)//
建樹inline
int find(int k)//
找到排名第k的數
if(k>sz[ch[now][0]]+1
)
return
now;
}}inline
void rever(int l,int r)//
翻轉void print(int x)//
中序遍歷並輸出
intmain()
print(rt);
return0;
}
P3391 模板 文藝平衡樹
題目鏈結 題目描述 您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列。其中需要提供以下操作 翻轉乙個區間,例如原有序序列是 543 215 4 3 2 1 5432 1,翻轉區間是 2,4 2,4 2,4 的話,結果是 523 415 2 3 4 1 52341。輸入格式 第一行兩個正整數 ...
P3391 模板 文藝平衡樹(Splay)
題目背景 這是一道經典的splay模板題 文藝平衡樹。題目描述 輸入輸出格式 輸入格式 第一行為n,m n表示初始序列有n個數,這個序列依次是 1,2,n 1,n m表示翻轉操作次數 接下來m行每行兩個數 l,r 資料保證 1 l r n 輸出格式 輸出一行n個數字,表示原始序列經過m次變換後的結果...
P3391 模板 文藝平衡樹(Splay)
基於這道題的關於splay的講解 將由這篇部落格開始。include include include include include include include include include include include include define lowbit x x x define ...