树套树乱讲

树套树乱讲

树状数组套线段树

先学会主席树。

主席树可以被理解为一个二维平面,其中n棵树可以视作横轴,每棵树中的坐标范围(也就是线段树的坐标范围)可以视作纵轴。这样一来就是用主席树维护了一些在二维平面上的点,给定(a,b,c,d),可以在(O(log{n}))的时间内求出满足(ale x_ile b,cle y_ile d)(i)的数量。

而树状数组套线段树就是把这个问题动态化。

对于上述的问题,我们是通过对主席树直接维护前缀和,查询时两棵主席树相减,再在区间([c,d])上查询答案的。既然已经维护了前缀和,那么一个单点修改就会涉及到(n)棵主席树从而使修改的时间复杂度炸裂。

那么现在我们就考虑用更为灵活的树状数组来维护前缀和。

把主席树的前缀和用树状数组的形式表示,每次单点修改时在(log{n})棵线段树上修改,查询时也是在(log{n})棵线段树上查。

时间复杂度(O(nlog^2{n}))

动态区间Kth

支持数组的单点修改,区间查Kth

单点修改就是树状数组的单点修改。

用树状数组维护前缀和,这时一个区间可以用(log{n})棵线段树与(log{n})棵线段树作差的形式来表示。

在线段树上二分,复杂度(O(nlog^2{n})) 代码1.9k

三位偏序(陌上花开)

第一维排序第二维树状数组第三维权值线段树
做完了,代码1.5k

【模板】二逼平衡树

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:

1、查询k在区间内的排名
2、查询区间内排名为k的值
3、修改某一位值上的数值
4、查询k在区间内的前驱(前驱定义为严格小于x,且最大的数,若不存在输出-2147483647)
5、查询k在区间内的后继(后继定义为严格大于x,且最小的数,若不存在输出2147483647)

树状数组套线段树。
1、查k的排名就是查区间内([1,k-1])的数的个数+1
2、排名为k的值,见动态区间Kth
3、树状数组修改
4、相当于操作二查排名为“([1,k-1])内数的个数”的值
5、相当于操作二查排名为“([1,k])内数的个数+1”的值

时间复杂度(O(nlog^2{n})),代码3.2k

[ZJOI2013]K大数查询

你有n个位置,每个位置初始是空的。
一种操作是在a位置到b位置上每个位置插入一个元素c
一种操作是查询a位置到b位置上第k大的数

报告!我会整体二分!不好意思,强制在线
首要考虑的是内外层的关系:位置和权值哪个作为内层,哪个作为外层?

方案一:外层位置内层权值。
发现操作一是一个区间修改,操作二是一个区间查询。不知道能不能写。

方案二:外层权值内层位置。
发现操作一是一个单点修改,操作二是一个线段树上二分。
所以就线段树套线段树,即线段树上的每一个点都是一棵线段树的根。

时间复杂度(O(nlog^2{n})),代码1.5k

[CTSC2008]网络管理

带修改树上路径Kth
报告我还是会整体二分!。。。
这题貌似也不好完全在线做
树套树——在dfs序上树状数组套线段树

之前因为没写过这题的树套树所以就直接口胡了一个(O(nlog^3{n}))的做法,回去想了想明明可以做到两个(log)的啊。
光速打脸。
做法参考SPOJ上那个Count on a tree,树套树外层维护每个点到根路径,那么修改一个点的点权时就会影响到一整棵子树,也就是一个连续的区间。查询的时候又是单点查询,这种“区间修改+单点查询”的操作只要差分以下就变成了“单点修改+前缀查询”,可以用树状数组做,复杂度(O(nlog^2{n}))
讲个笑话,树套树(O(nlog^2{n}))跑得比整体二分(O(nlog^3{n}))要慢

[HNOI2016]网络

给你一棵树,支持如下三种操作:

1、在树上插入一条两端点为(u,v),权值为(w)的链。
2、删除之前插入的某一条链。
3、查询未经过点(x)的链中的权值最大值

可在线。

首先把链剖成(log{n})个区间(dfs序上的区间)。
把区间反转,在不在这(log{n})个区间范围内的区域做覆盖。
这样就可以查询覆盖了(x)点的链中的最大值就可以了。

由于有删除操作所以线段树上的每个节点开一个删除堆。
时间复杂度(O(nlog^3{n})) 代码3.2k

后记

树状数组套平衡树我没写过,yyb说用来写三维偏序然而三位偏序不是被我树状数组套线段树水过去了吗
总之,大家根据自己的代码风格以及对这些数据结构的熟练程度进行取舍吧
还有对于那些没有强制在线的题目,采用cdq分治或者是整体二分都是不错的选择。

原文地址:https://www.cnblogs.com/zhoushuyu/p/8486133.html