P1527 | 你说得对,但是本题为「Forced Online Queries Problem」
你说得对,但是可以在线的题为什么要离线做呢?
鸣谢 @Querainy
考虑直接将经典的整体二分进行在线化处理:具体地,外层维护一棵权值线段树,结点
下面看看内层节点需要支持什么。容易发现只需要二维数点。如果暴力搞一棵主席树,空间复杂度达到
权值线段树的一只
发现我们只要 二维数点。那么我们有一个更加优秀的结构:Wavelet Tree。
Wavelet Tree 是一种非常好写的数据结构,可以理解为
考虑归并树状物在做什么。对于每一层,有用的信息其实只有
具体而言,我们从高位往低位扫一遍,每次按当前位 0/1 将序列划分成左右两段进行建树:
(从原论文里截的图,此处 rank 是数出现前缀次数,quantile 是区间求解 kth,与本题无关)
每次询问的时候,相当于数
- 如果
[p, q] 被[x, y] 完全包含,那么返回r - l + 1 。 - 如果
[p, q] 与[x, y] 无交,返回0 。 - 否则,递归到左右子树。注意到左右子树中
[l, r] 的下标是好维护的:当前层x 在左子树中对应下标是\text{count}_0(1, x) ,在右子树中则是\text{count}_1(1, x) + \text{count}_0(1, n) ,其中\text{count}_0(l, r) 表示下标[l, r] 中数在当前位中0 出现次数,\text{count}_1 同理。
可以证明上述过程的时间复杂度是
实现的时候一般不会显式把树建出来;维护当前层的 0-1 串即可。
另外为了处理横坐标重复的问题,可以暴力拆成多个横坐标,复杂度不变。
离散化完直接做就好了,时间
然后提交完发现 MTLE 了。原因是:压位数据结构在
如果你愿意的话也可以丢掉外层线段树的高
Code,无需刻意卡常即可通过。