1 条题解

  • 0
    @ 2025-10-28 11:28:22

    题目分析

    我们需要处理在时间限制下的路径规划问题,其中:

    • 每条道路有特定的开放时间窗口 [Li,Ri1][L_i, R_i-1]
    • 可以在城市中使用技能回到1秒前(但不能跨天)
    • 目标是 minimize 使用技能的次数

    关键观察

    1. 道路通行条件

    对于道路 ii,要在时刻 tt 通过,必须满足:

    LitRi1L_i \le t \le R_i - 1

    这意味着如果我们到达道路端点的时间是 tt,那么:

    • 如果 t<Lit < L_i,需要等待到 LiL_i
    • 如果 t>Ri1t > R_i - 1,需要回溯时间到 Ri1R_i - 1

    2. 时间回溯的代价计算

    设当前时间为 tt,目标时间窗口为 [l,r][l, r]

    • 如果 t<lt < l:需要等待,无代价
    • 如果 ltrl \le t \le r:可以直接通过,无代价
    • 如果 t>rt > r:需要回溯到 rr,代价为 trt - r

    因此通过一条道路的代价函数为:

    cost(t,l,r)=max(0,tr)\text{cost}(t, l, r) = \max(0, t - r)

    通过后的新时间为:

    $$\text{new\_time}(t, l, r) = \max(l, \min(t, r)) + 1 $$

    3. 问题转化

    对于查询 (A,B,C,D)(A, B, C, D)

    • 如果 A=CA = C:在同一城市,只需调整时间
    • 如果 A<CA < C:向右移动
    • 如果 A>CA > C:向左移动

    由于道路是独立的,我们可以将问题分解为:

    1. 计算从 (A,B)(A, B)(C,some time)(C, \text{some time}) 的最小代价
    2. 在终点处调整到目标时间 DD

    数据结构设计

    我们需要支持:

    • 区间查询:从位置 xx 到位置 yy 的最小代价
    • 单点修改:更新道路的开放时间

    线段树维护复合函数

    对于区间 [l,r][l, r],我们维护一个函数 f(t)f(t) 表示:

    • 输入:进入该区间的时间 tt
    • 输出:离开该区间的时间和使用技能的总次数

    由于代价函数是分段线性的,我们可以用 (a,b,c)(a, b, c) 三元组表示:

    $$f(t) = (\text{new\_time}, \text{cost}) = \begin{cases} (a_1 \cdot t + b_1, c_1) & \text{if } t \le \text{threshold}_1 \\ (a_2 \cdot t + b_2, c_2) & \text{if } \text{threshold}_1 < t \le \text{threshold}_2 \\ \vdots \end{cases}$$

    实际上,经过分析,每个区间的函数最多有 O(1)O(1) 个分段。

    函数复合

    f(t)=(tf,cf)f(t) = (t_f, c_f)g(t)=(tg,cg)g(t) = (t_g, c_g),则复合函数 h=gfh = g \circ f 为:

    $$h(t) = g(f(t)) = (t_g(t_f(t)), c_f(t) + c_g(t_f(t))) $$

    算法实现

    1. 节点信息

    每个线段树节点存储:

    • 对于向左移动和向右移动分别维护函数
    • 函数用 (l,r,a,b,c)(l, r, a, b, c) 表示:
      • 在时间区间 [l,r][l, r] 内,输出时间为 at+ba \cdot t + b,代价为 cc

    2. 合并操作

    合并两个相邻区间的函数时,需要考虑中间道路的约束:

    merge(f,g)=g(road(f(t)))\text{merge}(f, g) = g(\text{road}(f(t)))

    其中 road(t)\text{road}(t) 处理道路的时间约束。

    3. 查询处理

    对于查询 ACA \to C

    • 如果 A<CA < C:查询区间 [A,C1][A, C-1] 的向右移动函数
    • 如果 A>CA > C:查询区间 [C,A1][C, A-1] 的向左移动函数

    设查询结果为 (tarrive,cost)(t_{arrive}, cost),则最终答案为:

    answer=cost+max(0,tarriveD)\text{answer} = cost + \max(0, t_{arrive} - D)

    复杂度分析

    • 线段树建树:O(N)O(N)
    • 单点修改:O(logN)O(\log N)
    • 区间查询:O(logN)O(\log N)
    • 总复杂度:O((N+Q)logN)O((N+Q)\log N)

    核心公式总结

    1. 单条道路处理

      $$\begin{aligned} \text{cost}(t, L, R) &= \max(0, t - (R-1)) \\ text{new_{time}}(t, L, R) &= max(L, min(t, R-1)) + 1 \end{aligned} $$
    2. 函数复合: 设 f(t)=(tf,cf)f(t) = (t_f, c_f), g(t)=(tg,cg)g(t) = (t_g, c_g),则:

      $$g \circ f(t) = (t_g(t_f(t)), c_f(t) + c_g(t_f(t))) $$
    3. 最终答案计算

      $$\text{answer} = text{travel_{cost}} + \max(0, text{arrival_{time}} - text{target_{time}}) $$

    实现细节

    1. 使用动态开点线段树或zkw线段树
    2. 仔细处理函数的分段合并
    3. 注意边界情况(A=CA = C 的情况)
    4. 使用long long避免整数溢出

    这个解法充分利用了问题的组合结构,通过函数复合的方式高效处理路径查询,满足了大数据规模的要求。

    • 1

    信息

    ID
    4454
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者