什么?树套树?不存在的。
传送门
在您开始阅读本题解之前,蒟蒻我建议您先把题面多看几遍,并仔细阅读样例和样例说明。
我才不会告诉你蒟蒻我就是因为看错题面然后白忙活了一个小时。
题解
据说本题可以用树套树解,但是树套树这种东西常数稍微一大就TLE,这位dalao的树套树就咕掉了。而且树套树对于蒟蒻我来说太*难了,所以我们需要整体二分这种东西。
首先确保您已经掌握普通二分的写法,不会普通二分的请自行Ctrl+w。
整体二分的主要思想就是把这一大坨询问一起处理。
首先让我们来考虑只有一个询问操作的情况:
二分权值(即答案),每次分到一个$mid$,我们就把这个询问之前所有的有贡献的添加操作(即$c$值大于$mid$的添加操作)用一个支持区间修改的树状数组或者线段树预处理,然后我们就可以很快地得到区间$[a,b]$中权值大于$mid$的数的个数$tot$。如果$tot$小于这个询问操作的$c$值,那么我们就把$c$值减去$tot$,然后把之前产生过贡献的添加操作扔掉删除,并修改二分的边界值继续二分;否则直接修改二分的边界值继续二分即可。
好了现在再来考虑有一坨询问的情况。
方便起见,我们把询问操作和添加操作一起处理。设当前二分的值是$mid$,二分的权值区间是$[L,R]$要处理的操作区间是$[s,t]$。那我们先遍历一遍操作区间,如果当前遍历到的是有贡献的添加操作,就更新一下线段树;若果是询问操作,就在线段树上查询一下该询问区间内权值大于$mid$的个数$tot$,根据$tot$是否大于$c$并把操作分成两堆,然后递归分别处理两堆,直到$L=R$时$mid$就是当前所有询问操作的答案。(添加操作也要根据$c$值是否大于$mid$也一起分成两堆)
注意将操作分堆时每一堆内不要打乱操作的顺序。
时间复杂度$\Theta(n\log^2{n})$,常数是真的小QwQ。
代码
貌似真的比树套树好懂
1 |
|