假设添加这些所有区间,区间数量肯定是不行的;但是分别考虑这两种区间,假设两个 k 同时出现了相同的区间,那么显然应该保留大的 k 的区间。对于新的有用区间,其实在 vl[1]\cap vr[len/2] 中会全部出现,这意味着总共新的不同的有用区间个数只有子树大小(指在原序列上的个数)的两倍(一左一右),每个新区间最后保留一个;对于轮廓线上的有用区间,同样每个有用区间只会保留一个(最终都会出现在 vl[len/2]\cup vr[len/2] 中)。对于上面区间在轮廓线内的情况,同样最终也只保留一个。
这里应该有一张图片:
其中蓝色代表新加的有用区间,绿色代表轮廓线的有用区间。
也就是说上述区间总数就是两个儿子的区间总数加自己新添加的区间数量,即加上了两倍子树大小(原序列在值域区间上的元素个数)。这样每个节点的有用区间个数上限就是 2size\times de 个。
至此我们从做法上构造性证明了原本关于有用区间个数的结论,以下给出具体的算法。
关键在于如何求交。对于新添加区间,找到投射在轮廓线上的新区间并不难,因为最后新的有用区间只有线性个,所以可以预处理好,简单查对应的 k 即可。对于轮廓线上的区间,从大到小枚举 k 相当于在不停的删轮廓线上的有用区间,删的是一个区间的,这个问题可以用经典的线性序列并查集解决。最终算法的复杂度是关于所有节点有用区间总数 2^n\times n^2 的线性,即复杂度依然为 O(2^n\times n^2)。