1 条题解

  • 0
    @ 2025-10-29 19:59:07

    题解

    问题分析

    题目要求模拟α岛的管理体系:从0级管理者(喝喝粥)开始,每级管理者将自己管辖区域外的4个子区域分封给下一级小弟,下一级小弟根据规则(a_k=0选最低点,a_k=1选最高点)选择站位,并记录其直接上级(大哥)的高度。最终输出每个位置的管理者的大哥高度(无管理者或0级管理者为0)。

    核心挑战是高效处理区域划分与最值查询:随着层级增加,区域不断细分,需快速找到每个子区域的最值点(最低/最高),并递归处理子区域。

    关键思路

    1. 分治递归划分区域
      每个管理者的管辖区域是一个矩形[lx, rx]×[ly, ry],选择该区域的最值点(根据a_k)作为当前级管理者后,将区域划分为4个子区域(A:左上[lx, mx-1]×[ly, my-1]、B:右上[lx, mx-1]×[my+1, ry]、C:左下[mx+1, rx]×[ly, my-1]、D:右下[mx+1, rx]×[my+1, ry]),递归处理下一级(k+1)。

    2. 高效区间最值查询
      为避免每次查询区域最值时暴力遍历(时间复杂度太高),对每行构建类似线段树的结构(mxmn数组),支持O(log m)时间查询任意列区间[ly, ry]的最大值或最小值的列索引,进而快速定位该区域的最值点。

    3. 处理行列维度差异
      n < m时,交换nm统一处理逻辑(将列视为行),最终输出时再转换回原坐标,简化代码实现。

    算法步骤

    1. 输入处理与坐标映射
      读取n, m, a数组和高度矩阵h,通过id1(i,j)将二维坐标(i,j)映射为一维索引,便于数组存储。

    2. 线段树结构构建
      对每行i,构建mx(区间最大值列索引)和mn(区间最小值列索引)数组。采用类似线段树的方式,叶子节点对应单个列,非叶子节点存储子区间的最值列索引,支持高效区间查询。

    3. 递归分治处理区域
      从初始区域[1, n]×[1, m]开始,调用solve函数:

      • 若区域为空(lx > rxly > ry),直接返回;
      • 根据a_k查询当前区域的最值点(mx, my),记录其大哥为上一级管理者的高度F
      • 递归处理4个子区域,下一级k+1的大哥为当前最值点的高度。
    4. 输出结果
      根据nm的大小关系,按原坐标顺序输出结果矩阵ans

    代码解析

    • 坐标映射id1(i,j)(i,j)转换为一维索引((i-1)*m + j),id2(i,j)用于线段树结构的索引(每行独立的线段树)。
    • 线段树构建:对每行i,从叶子节点(j + m - 1)开始,向上合并区间,mn[id2(i,j)]存储区间j对应的列区间的最小值列索引,mx同理存储最大值列索引。
    • 递归函数solve:核心逻辑,查询当前区域的最值点,记录大哥信息,递归处理4个子区域。
    • 维度适配:当n < m时交换nm,统一处理后再按原维度输出,避免重复代码。

    复杂度分析

    • 时间复杂度O(nm log m)。每个区域的最值查询通过线段树优化为O(n log m)(每行O(log m)),递归深度为O(min(n,m)),总复杂度由所有区域的查询成本累加得到,最终为O(nm log m)(因每个地块仅被处理一次)。
    • 空间复杂度O(nm)。用于存储高度矩阵、结果矩阵及线段树结构(mxmn数组,大小为2*n*m)。

    综上,算法通过分治递归与区间最值优化,高效模拟了各级管理者的分封过程,适用于n×m ≤ 4e6的大规模输入。

    • 1

    信息

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