ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UOJ191口胡

2022-02-06 21:35:06  阅读:145  来源: 互联网

标签:二分 log 询问 离线 查询 2n UOJ191


UOJ191,你失败的原因只有一个:你没有强制在线。

首先这个序列末位加加减减很烦,于是换成操作树,这样就变成查询链的信息了。

注意到一个向量 \((x_1,y_1)\) 比 \((x_2,y_2)\) 优秀的条件是 \(x_1*B+y_1*A>x_2*B-y_2*A\),也就是 \((x_1-x_2)*B>(y_1-y_2)*A\),\(\frac {x_1-x_2}{y_1-y_2}>\frac A B\)。

于是树剖。

容易发现询问是又链上若干个前缀与一个区间组成的。于是我们似乎只需要实现一个可持久化分块,然后在上面二分即可。

但是最后那个区间怎么办?别急,我们后面再进行讨论。

如果直接使用平衡树复杂度应该是十分优秀的 \(O(m\log^2n)\),加上平衡树的大常数能过就有鬼了。

考虑进行神秘优化。

将对前缀的询问拆下来,然后提前对每条链建立好凸包,凸包应该包含的信息有坐标和在树上的深度。然后离线对斜率排序。

每次询问之前将凸包的指针向后跳(相当于预处理处理二分的位置),因为每个数最多被跳一次所以是 \(O(n)\) 的。

每次询问凸包时需要询问凸包上的“前驱”(前面第一个没被标记的)和“后继”(类似前者),将查询的位置与查询的值再次离线下来。

现在的问题变为查询序列上前面第一个比自身小的值与后面第一个比自身小的值。

将序列的元素从大到小排序,每扫到一个元素就将自己与前面的元素合并,然后前面第一个比自身小的值相当于前面第一个块的最后一个元素,后继同理。

使用并查集即可做到 \(O(m\log n\alpha(n))\)。排序使用基数排序即可保证复杂度。虽然说也有严格的线性序列并查集就是了

但是你一共有 \(O(m\log n)\) 个询问啊?

对询问分块,分成 \(\log n\) 块,每一块只有 \(O(m)\) 个询问,这样子离线就可以接受了。

但是别忘了还有一些区间。但是数量已经降低到 \(O(m)\) 个了。

对前面的故技重施,但是变成了查询前面第一个在 \([l,r]\) 中的元素。因为只有 \(O(m)\) 个询问所以可以随便用主席树。

但是计算空间的时候你会发现空间刚好是 65MB。。。

考虑二分这个值的位置。问题变为查询矩阵中数的个数。

这个差分一下用树状数组即可。但是这样还需要离线,所以不妨直接把二分搬到最外面去,变成整体二分。

这样子做的常数极小,虽然是 \(O(m\log^2n)\) 却比 \(O(m\log n)\) 快不少。毕竟主席树的大常数应该都听说过了

最终复杂度 \(O(n\log n+m\log n\alpha(n)+m\log^2n)\) 或 \(O(n\log n+m\log^2n)\),空间复杂度 \(O(n+m)\),也许大概可以通过此题。

标签:二分,log,询问,离线,查询,2n,UOJ191
来源: https://www.cnblogs.com/lmpp/p/15866387.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有