【“树套树”简介】
树套树不是一种单一的数据结构,而是一种把两种树形结构(如线段树、平衡树、树状数组等)组合在一起的解题思想,主要用来处理复杂的区间查询和修改问题 。
一、树套树到底是啥?
1.核心逻辑
简单说就是“俄罗斯套娃”,外层树的每一个节点,里面都藏着一棵内层树 。
2.分工明确
外层树:通常用来管位置,比如维护数组的下标区间 。
内层树:用来管数值,比如维护这个区间里具体有哪些数、数的排名等 。
3.解决痛点
单独一棵树搞不定的时候,比如又要改区间、又要查第 k 小的数,套一层就能把二维的信息压在一起处理 。
二、常见搭配有哪些?
1.线段树套平衡树
怎么配:外层用线段树切分区间,每个节点里放一棵平衡树(如 Treap、Splay) 。
能干嘛:适合查区间里某个数的排名、前驱后继,或者区间第 k 小 。
2.树状数组套主席树
怎么配:外层用树状数组维护前缀和,内层用主席树(权值线段树)维护数值分布 。
能干嘛:专门对付带修改的区间第 k 小问题,比线段树套平衡树常数小一点 。
3.线段树套线段树
怎么配:外层内层都是线段树,内层通常要动态开点,不然内存爆得很快 。
能干嘛:适合二维平面上的单点修改、区域查询,比如数某个矩形范围内有多少个点 。
三、用起来有什么代价?
1.时间成本
操作慢:因为要跳两层树,查询和修改的时间复杂度通常是O(log₂²n),比单棵树多一个 log。
常数大:实际运行起来比理论值更慢,尤其是线段树套线段树,指针跳来跳去很费时 。
2.空间成本
吃内存:如果内层树不开动态开点,空间会直接炸到 O(n²),必须动态开点才能控制在O(nlog₂n) 或 O(nlog₂²n) 。
3.编写难度
代码极长:要写两棵树的完整功能,代码量轻松超过 200 行,调试起来非常痛苦 。
容易写错:节点索引、内存回收这些地方稍不注意就会段错误,比赛时除非没办法,一般不会首选。
【参考文献】
https://www.cnblogs.com/little-uu/p/15023553.html
https://www.cnblogs.com/IzayoiMiku/p/14679662.html
https://blog.csdn.net/qq_56326461/article/details/140330377
https://www.cnblogs.com/captain1/p/10193468.html
https://blog.csdn.net/weixin_43980799/article/details/104527921
https://blog.csdn.net/weixin_43980799/article/details/104527921
https://blog.csdn.net/GROZAX/article/details/129978379
https://blog.csdn.net/qq_46105170/article/details/121579396
https://www.acwing.com/problem/content/2490/
“树套树”简介