加载中...

5.8 —— 879D

879D

限时每日一题day32。一道看着不怎么难的题,性质也是一眼挖掘,但在实现时唐了,没做出来qwq。

显然可以钦定某两条线段作为 \(max\)\(min\),因此可以想到枚举其中一条,快速找到与其对应的那条最优线段。

对于一对线段所产生的答案只有三种情况:

  1. 两条线段相离 —— 取最长的为答案
  2. 两条线段相交 —— 两条线段均去掉重叠的一段,取两条线段剩下的最大值
  3. 两条线段互相包含 —— 长线段 \(len\) - 短线段 \(len\) 即为答案

将所有线段按照左端点排序,枚举每条线段。对于情况1和2,可以二分大于当前线段右端点的第一个左端点所对应的线段,则左侧所有线段与其相交,右侧所有线段与其相邻。可以使用 \(ST\) 表分别维护 左侧所有线段的最大右端点 与 右侧所有线段的最长长度 来得到答案。

对于情况3,想着仍然用 \(ST\) 表的思路来做,结果想半天没想出来。其实这时就应该想到通过利用动态结构来实时维护信息。钦定正在枚举的线段为被包含的线段,那么显然,包含这条线段的其他所有线段一定只会出现在之前枚举过的所有线段中(因为按左端点升序排序,包含这条线段的充要条件为左端点不超过当前线段的左端点,同时右端点至少为当前线段的右端点)。因此可以用树状数组来维护这些线段的信息——以右端点为树状数组下标(需要离散化),长度作为值,那么问题就转化为了动态查询前缀最大值。由于修改时只会添加线段,因此修改后的值一定不会比原来的值小(注意只有满足这一点,才能用树状数组来做,否则就要上线段树了)。答案即为上述3种情况答案最大值的2倍。

code

posted @ 2025-05-08 17:46  jxs123  阅读(26)  评论(0)    收藏  举报