长夜伴浪破晓梦,梦晓破浪伴夜长。

· · 题解

P10882 [JRKSJ R9] ZYPRESSEN

咕了一个月后来补题解。

第一眼支配对,然后没有第二眼了。

  • 给出序列 (a_1,\dots,a_n)q 次询问 l,r,求 l\le i<j<k\le r 且存在以 a_i,a_j,a_k 为三边长度的三角形的三元组 (i,j,k)a_i+a_j+a_k 最小值。

考虑按照二进制最高位将值域划分成若干个块,记 B_m=[2^m,2^{m+1})。设值域为 V

显然不用考虑 (i,j,k) 之间的大小关系,只要求她们不同且都在区间里面就一定可以将三元组写成递增的形式。注意到同块中任意三个元素均能作为三角形边长,因此对于每个询问,考虑找到最小的 m 使得 (a_l,\dots,a_r)B_m 中有 \ge3 个元素。此时选取前三小值即可。线段树维护之,合并可以看成左右儿子信息归并。

这里可以考虑从小到大枚举每个块,再枚举询问,更新所有未被标记且在她中有 \ge 3 个元素的询问,然后标记这个询问。每个询问至多被标记一次,这时才会触发查询,因此时间复杂度为 \mathcal{O}(q\log n)

对于剩下的方案,如果想要更优,则必须至少存在一个 <2^k 的元素。判断区间中某块内的元素个数可以先预处理该块内元素的前缀出现次数然后前缀相减。枚举每个块时都要处理一次,时间复杂度为 \mathcal{O}(n\log |V|)

到这里基本结束了。时间复杂度为 \mathcal{O}((n\log |V|+q)\log |V|),空间复杂度为 \mathcal{O}(q\log |V|+|V|)。如果扫描线时使用高级点的数据结构可以做到更优时间复杂度。空间带 |V| 的原因是对于每种 e_k 开了单调栈,如果离散化可以做到更优。

然后我的实现被卡常了,加了指令集也会不时被卡。联系出题人要求时限增大 0.5\text{ s} 未果。建议被卡常的找个夜深人静的时候多交几发试试。

AC Link / Code