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