主席树与二维数点问题
前言:
自己在网上搜索了很久,都没有看到具体是怎么维护的,下课问了下,一下就点醒了。
正文:
先考虑主席树和二维数点有什么关系。
我们可以将y轴看成一个时间轴。
我们查询y1-y2之间的数字时,其实就是查询这些版本下的x1-x2的区间和,最后由于可加性,直接差分相减即可。
然后我写着写着,在差分那里愣住了。
就是说要是我要修改x,y的话,就是修改时间为y的线段树,很容易。
问题在于,这是差分啊!我必须要把y和y以后的所有都+1才对。这样时间复杂度就是戳的。
所以说,我们必须要加完所有的点,再询问,时间复杂度才是对的(相当于在中间做了个线段树合并)
或者说,可以在中途加一个树状数组多一个log来搞混杂的这些东西。
当然了,其实也不需要合并这么做。
竟然我加点和查询分开了的话,我直接给点按照y排个序就好了......
假如说这一排新加了点x,那么我直接继承上一次的线段树,在x处修改变为这一次的就好了......
(感谢老师点醒我x2)
带权值的点也可以这样做。(就不是+1了)
一道题可以试着用主席树维护。
拓展:
其实呢,有个东西叫做二维树状数组,就是上面那道题的板子。
但是这对数组大小会有严格的限制,这就是主席树的优势。他可以做到n和m双1e5的样子。
打码思路:
首先所有点按照时间先后为第一关键字,位置为第二关键字排序(有时候要去重)。
这里我一般用x作为时间。
每一次遇到新的时间点,继承上一次的root,开新的主席树,直接做。(注意要是中间有“跳行”情况,也要直接继承,不然就中断了前缀和)
利用差分求解区间和即可。