平衡樹 treap學習筆記(3)

2021-08-11 02:00:47 字數 1535 閱讀 1252

在(2)中我們寫了無旋treap。然後我就找到了那道題qaq。

文藝平衡樹

題目描述

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

輸入輸出格式

輸入格式:

第一行為n,m n表示初始序列有n個數,由1-n組成 m表示翻轉操作次數。

輸出格式:

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

之前的treap裡按權值維護,是一顆二叉查詢樹。而在這道題中好像和二叉查詢樹沒什麼關係。。

不過我們發現無旋treap只有在insert時維護了二叉查詢樹的性質。(這道題我們並用不到,我們要的是原數列)。然後我們知道笛卡爾樹的中序遍歷是原數列。所以我們能不能仿照笛卡爾樹建樹呢?

引用的話。

二叉排序樹的各種操作是不改變樹的中序遍歷的。所以這道題可以用各種二叉搜尋樹的操作。

我們可以用區間線段樹的思想,加乙個懶標記,然後操作時pushdown翻轉。所謂翻轉就是在要交換的區間樹中交換左右兒子。(把要交換的區間拆出來)然後再合併回去。

最後中序遍歷樹 這樣就巧妙地求出了區間翻轉後的序列。

//補充:普通平衡樹維護點權二叉搜尋樹,文藝平衡樹維護陣列下標二叉搜尋樹。

#include

using

namespace

std;

#define ll long long

#define mp make_pair

const

int maxn=1e6;

const

int inf=1e9;

typedef pairpar;

int n,m;

struct treap

inline

void pushdown(int p)

}par split(int p,int x)

if(x==size[l]+1)

if(xreturn mp(tem.first,p);

}par tem=split(r,x-size[l]-1);

rson[p]=tem.first;pushup(p);return mp(p,tem.second);

}int merge(int x,int y)

else

}void build(int &p,int l,int r)

int mid=(l+r)>>1;

w[++cnt]=mid-1;prio[cnt]=rand();size[cnt]=1;lzt[cnt]=0;p=cnt;

build(lson[p],l,mid-1);

build(rson[p],mid+1,r);

pushup(p);

}void dfs(int p)

}treap;

int main()

treap.dfs(treap.rt);

return

0;}

平衡樹之Treap

乙個集合支援快速插入 刪除乙個數字。支援快速查詢乙個數字在所有已插入數字中的排名。支援刪除大小在某乙個區間內的數字。動態維護乙個數列。可以在數列的任何位置插入刪除,求區間和,min,max,進行區間翻轉 這就需要用到二叉查詢樹 binary search tree 性質 這是一棵二叉樹。對於任意乙個...

Treap 普通平衡樹

最近學習了treap,找了道題目做做 全抄hz.因為普通的二叉樹,會退化成鏈 所以你把讀入打亂順序再構造二叉樹,就明顯卡不掉 平平均深度logn treap就是這樣的 在插入乙個數時,我們搞乙個rnd,賦值隨機 然後如果當前的這個節點rnd小於其父節點,那麼就把他轉到父節點的位置 這樣好比是給這個節...

平衡樹模板 Treap

演算法標籤 treap 種下第一棵平衡樹 這是一道模板題。如果覺得這個題水的可以做一下4544壓行,是千古神犇花爸爸出的神犇題。您需要寫一種資料結構 可參考題目標題,但是這句話其實並沒有什麼用233 來維護一些數,其中需要提供以下操作 1.插入x數 2.刪除x數 若有多個相同的數,因只刪除乙個 3....