樹套樹是乙個十分神奇的演算法,種類也有很多:像什麼樹狀陣列套主席樹、樹狀陣列套值域線段樹、\(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,...