1 条题解

  • 0
    @ 2025-10-27 15:08:06

    题目分析
    本题模拟小 E 在动态增加的砖摞上进行搬砖的过程,需要高效处理两种操作:添加新砖摞和查询给定初始精力值下的工作时间。

    关键观察

    • 每次操作时,小 E 会从所有砖摞的顶部同时搬走最多 dd 块砖(dd 为当前精力值)
    • 当一摞砖被完全搬完时,小 E 的精力值会下降该砖摞对应的 bb
    • 停止条件:
      1. 没有新的砖摞被完全搬完
      2. 精力值 0\le 0
      3. 所有砖已被搬完(但当前小时仍计入工作时间)

    算法思路
    由于数据规模较大(T351493T \le 351493),需要高效处理:

    核心思想:分块 + 并查集优化

    • 将砖块数量范围 [1,100000][1, 100000] 分成 N\sqrt{N} 个块
    • 每个块维护:
      • 该块内砖摞数量的前缀和
      • 该块内砖摞总块数的前缀和
      • 并查集结构快速找到下一个非空砖摞

    状态设计

    • num[i], sum[i]:原始前缀和数组
    • mkn[i], mks[i]:块级别的懒标记
    • id[i]:从位置 ii 开始的下一个非空砖摞位置
    • mn[i]:块 ii 内的最小非空砖摞位置
    • pa[d][x]:对于步长 dd,从 xx 开始的下一个可达位置

    操作处理

    1. 添加操作(op=1)

      update(a, b):
        更新前缀和数组 num 和 sum
        如果 b>0,更新 id 和 mn 数组
        更新并查集 pa,维护跳跃指针
      
    2. 查询操作(op=2)

      初始化 x=0, ans=0
      while d > 0:
        ans++  // 开始新的一小时
        if 区间[x+1, x+d]内没有砖块: break
        
        if d <= 块大小:
          使用并查集快速跳到下一个有砖的位置
          计算中间的空闲距离,直接跳过
        
        x += d  // 搬砖
        d -= 区间[x-d+1, x]内的砖块总重量对应的精力下降
      

    关键优化技巧

    1. 分块处理

      • 10510^5 分成约 300 块
      • 块内维护前缀和,块间用懒标记
    2. 并查集跳跃

      • 对于每个可能的步长 dNd \le \sqrt{N},维护并查集
      • pa[d][x] 表示从 xx 开始,步长为 dd 时下一个有砖的位置
    3. 快速区间查询

      • 使用分块前缀和 O(1)O(1) 查询区间砖块总数
      • 使用 idmn 数组 O(N)O(\sqrt{N}) 找到下一个非空位置

    代码结构

    // 数据结构
    vector<pi> eg[maxn];  // 邻接表(示例残留,实际未使用)
    int num[100005], sum[100005];      // 前缀和数组
    int mkn[100005], mks[100005];      // 块懒标记
    int id[100005], mn[100005];        // 下一个非空位置
    int pa[305][100005];               // 并查集跳跃
    int st[405], ed[405], bl[100005];  // 分块信息
    
    // 核心函数
    void build():          // 初始化分块
    void update(x, k):     // 添加砖摞
    void ins(x):          // 更新非空位置信息
    int query(d):         // 查询工作时间
    

    算法正确性

    • 基础模拟:严格遵循题目描述的搬砖规则
    • 优化等价:跳跃优化不改变实际搬砖顺序,只是跳过无砖区域
    • 边界处理:正确处理精力值降为 0、砖块搬完等边界情况

    复杂度分析

    • 预处理O(NN)O(N\sqrt{N}) 初始化并查集
    • 添加操作O(N)O(\sqrt{N}) 更新块信息
    • 查询操作:均摊 O(N)O(\sqrt{N}),最坏 O(NlogN)O(\sqrt{N} \log N)

    样例验证
    样例1:初始精力3 → 工作3小时
    样例2:初始精力4 → 工作4小时
    与题目描述完全一致,证明算法正确性。

    该算法通过分块和并查集的巧妙结合,在大数据规模下高效模拟了搬砖过程,是典型的离线查询优化解决方案。

    • 1

    信息

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