洛谷 P3391 模板 文藝平衡樹

2021-10-02 09:56:04 字數 1738 閱讀 6684

真正的模板題,先用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,...