洛谷 P3391 模板 文藝平衡樹

2022-05-03 18:48:08 字數 1689 閱讀 3091

這是一道經典的splay模板題——文藝平衡樹。

您需要寫一種資料結構,來維護乙個有序數列,其中需要提供以下操作:翻轉乙個區間,例如原有序序列是5 4 3 2 1,翻轉區間是[2,4]的話,結果是5 2 3 4 1

輸入格式:

第一行為n,m(n,m<=100000) n表示初始序列有n個數,這個序列依次是(1,2, \cdots n-1,n)(1,2,⋯n−1,n) m表示翻轉操作次數

接下來m行每行兩個數 [l,r][l,r] 資料保證 1 \leq l \leq r \leq n1≤l≤r≤n

輸出格式:

輸出一行n個數字,表示原始序列經過m次變換後的結果

輸入樣例

5 3

1 31 3

1 4

輸出樣例

4 3 2 1 5

splay模板題,維護該序列的中序遍歷不變,然後每次通過旋轉節點使操作的區間變作一顆字樹,然後打上標記即可。

什麼是splay?

一棵伸展樹......

什麼是伸展樹?

最近剛學,我個人的理解,大概就是乙個能在不破壞二叉搜尋樹結構(即中序遍歷始終為公升序)的情況下

通過旋轉乙個節點到他根節點位置使得操作區間恰好全部位於一棵子樹內的方法。

然後就打上標記,之後在類似線段樹一樣的pushdown傳遞資訊就好了。

**如下:

#include#include

#include

#include

#include

#define ll long long

#define mod

#define mid (r+l>>1)

#define m 2000010

using

namespace

std;

ll read()

ll n,m,l[m],r[m],tp[m],ad,sz[m],tg[m],ace,a,b,p,q,cnt;

bool flag=false

;void

pushdown(ll x)

void pushup(ll x)

ll build(ll l,ll r,ll rt)

void

rotate(ll x)

if(l[top]==x) l[top]=r[x],tp[r[x]]=top,r[x]=top;

else r[top]=l[x],tp[l[x]]=top,l[x]=top;

pushup(top),pushup(x);

}void

oper(ll x)

ll top=tp[x];

pushdown(top);

if(tp[top]==ace) rotate(x);

else

if(l[l[tp[top]]]==x||r[r[tp[top]]]==x) rotate(top);

else

rotate(x);

}ll find(ll x,ll pos)

void

ans(ll x)

ans(r[x]);

}int

main()

ans(ace);

return0;

}

我這裡還是寫的比較模糊,我也是通過了解別人的部落格才理解了splay

就是這個 -> 

洛谷 P3391 模板 文藝平衡樹

真正的模板題,先用splay把這個題打熟了再來做這個題qwq splay的基本操作我就不講了,直接說一說這個題的做法 首先我們把序列放到一棵樹上,使得這棵樹的中序遍歷為原序列,這個建樹操作和線段樹類似,遞迴建立左右兒子,然後進行兩個操作 f in dfind find 獲取序列第x xx位置上的值 ...

洛谷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,...