P3391 模板 文藝平衡樹(Splay)

2022-05-20 01:51:57 字數 1328 閱讀 3863

傳送門

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 ...