初學樹套樹 線段樹套Treap

2022-05-14 15:34:35 字數 2589 閱讀 4013

樹套樹是乙個十分神奇的演算法,種類也有很多:像什麼樹狀陣列主席樹樹狀陣列值域線段樹\(zkw\)線段樹套\(vector\)等等。

不過,像我這麼弱,當然只會最經典的線段樹套\(treap\)啦。

線段樹我相信大家都會的,\(treap\)可以看一下這篇部落格:簡析平衡樹(二)——treap

線段樹套\(treap\)的思想其實非常簡單。

簡單的說,就是有一棵線段樹,它的每乙個節點都是一棵\(treap\),每個\(treap\)裡面都儲存了這個節點所表示的區間裡的所有的元素。聽起來都很強大。

下面是乙個很嚴肅的問題:線段樹套\(treap\)有什麼用?

其實也很簡單,差不多就是將\(treap\)的詢問操作前面全部加了區間二字。

具體如下:

然後你就能輕鬆\(a\)掉此題:【洛谷3380】【模板】二逼平衡樹(樹套樹)。

接下來,我們來講一講上面提到的這些操作具體是如何實現的。

一、查詢乙個元素\(val\)在區間內的排名

單次操作時間複雜度:\(o(log^2n)\)【線段樹上找區間:\(o(logn)\),\(treap\)查詢排名:\(o(logn)\)】。

二、查詢區間內排名為\(rk\)的元素

這個操作相比其他操作就略有些複雜了。

直接查詢過於麻煩,而且難以實現,所以我們可以二分這個元素,然後通過查詢排名來判斷這個元素大了還是小了即可。

單次操作時間複雜度:\(o(log^3n)\)【二分:\(o(logn)\),樹套樹查詢排名:\(o(log^2n)\)】。

三、修改某一位的值

單次操作時間複雜度:\(o(log^2n)\)【線段樹上找區間:\(o(logn)\),\(treap\)刪除+插入:\(o(logn)\)】

四、查詢乙個元素\(val\)在區間內的前驅

單次操作時間複雜度:\(o(log^2n)\)【線段樹上找區間:\(o(logn)\),\(treap\)查詢前驅:\(o(logn)\)】。

五、查詢乙個元素\(val\)在區間內的後繼

單次操作時間複雜度:\(o(log^2n)\)【線段樹上找區間:\(o(logn)\),\(treap\)查詢後繼:\(o(logn)\)】。

#include#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)<(y)?(x):(y))

#define uint unsigned int

#define ll long long

#define ull unsigned long long

#define swap(x,y) (x^=y,y^=x,x^=y)

#define abs(x) ((x)<0?-(x):(x))

#define inf 2147483647

#define inc(x,y) ((x+=y)>=mod&&(x-=mod))

#define n 50000

using namespace std;

int n,tot=0,a[n+5];

struct tree

node[n*30+5];

class fio

else x=0;

}else if(node[x].val>val) del(node[x].son[0],val);

else del(node[x].son[1],val);

pushup(x);

}public:

class_treap()

inline bool empty()

inline void insert(int val)

inline void delete(int val)

inline int get_rank(int val)//與傳統的get_rank()有點區別,這裡的get_rank()求的是小於val的值的個數

return rk;

}inline int get_val(int rk)

}inline int get_pre(int val)

};class class_segmenttree//線段樹

inline void upt(int l,int r,int rt,int pos,int val)//修改

inline int get_rank(int l,int r,int rt,int ql,int qr,int val)//求區間排名

//二分答案

inline int getpre(int ql,int qr,int val)

inline int getnxt(int ql,int qr,int val)

}segmenttree;

int main()

}return f.end(),0;

}

樹套樹 線段樹套set

請你寫出一種資料結構,來維護乙個長度為 n 的序列,其中需要提供以下操作 1 pos x,將 pos 位置的數修改為 x。2 l r x,查詢整數 x 在區間 l,r 內的前驅 前驅定義為小於 x,且最大的數 數列中的位置從左到右依次標號為 1 n。區間 l,r 表示從位置 l 到位置 r 之間 包...

線段樹套Treap

題目為bzoj1901.單點修改區間第k大,如果卡記憶體你要怎麼辦 hq說線段樹套平衡樹比樹狀陣列套線段樹好得多 所以我就寫了 然後就寫了 n log 3n 在zju上t掉了qaq 卡記憶體還卡時間真是有夠過分 其實就是外層線段樹存一下根然後按照正常的treap寫就好了,但是有乙個問題就是treap...

POJ 2155 樹套樹 線段樹套線段樹

matrix 樓教主出的題目。題意 乙個矩陣初始值都為0,每次給 c x1 y1 x2 y2 去反轉這個矩陣。或者 q x1 y1 查詢這個點是0 1。第一次接觸樹套樹的題目。一句ac 對於基本的線段樹,再在每個節點建乙個y方向上的線段樹。tree n m 這道題目更新的時候,對於x方向就是 x1,...