1 条题解
-
0
题解
问题分析
题目要求模拟α岛的管理体系:从0级管理者(喝喝粥)开始,每级管理者将自己管辖区域外的4个子区域分封给下一级小弟,下一级小弟根据规则(
a_k=0选最低点,a_k=1选最高点)选择站位,并记录其直接上级(大哥)的高度。最终输出每个位置的管理者的大哥高度(无管理者或0级管理者为0)。核心挑战是高效处理区域划分与最值查询:随着层级增加,区域不断细分,需快速找到每个子区域的最值点(最低/最高),并递归处理子区域。
关键思路
-
分治递归划分区域:
每个管理者的管辖区域是一个矩形[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)。 -
高效区间最值查询:
为避免每次查询区域最值时暴力遍历(时间复杂度太高),对每行构建类似线段树的结构(mx和mn数组),支持O(log m)时间查询任意列区间[ly, ry]的最大值或最小值的列索引,进而快速定位该区域的最值点。 -
处理行列维度差异:
当n < m时,交换n和m统一处理逻辑(将列视为行),最终输出时再转换回原坐标,简化代码实现。
算法步骤
-
输入处理与坐标映射:
读取n, m, a数组和高度矩阵h,通过id1(i,j)将二维坐标(i,j)映射为一维索引,便于数组存储。 -
线段树结构构建:
对每行i,构建mx(区间最大值列索引)和mn(区间最小值列索引)数组。采用类似线段树的方式,叶子节点对应单个列,非叶子节点存储子区间的最值列索引,支持高效区间查询。 -
递归分治处理区域:
从初始区域[1, n]×[1, m]开始,调用solve函数:- 若区域为空(
lx > rx或ly > ry),直接返回; - 根据
a_k查询当前区域的最值点(mx, my),记录其大哥为上一级管理者的高度F; - 递归处理4个子区域,下一级
k+1的大哥为当前最值点的高度。
- 若区域为空(
-
输出结果:
根据n和m的大小关系,按原坐标顺序输出结果矩阵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时交换n和m,统一处理后再按原维度输出,避免重复代码。
复杂度分析
- 时间复杂度:
O(nm log m)。每个区域的最值查询通过线段树优化为O(n log m)(每行O(log m)),递归深度为O(min(n,m)),总复杂度由所有区域的查询成本累加得到,最终为O(nm log m)(因每个地块仅被处理一次)。 - 空间复杂度:
O(nm)。用于存储高度矩阵、结果矩阵及线段树结构(mx和mn数组,大小为2*n*m)。
综上,算法通过分治递归与区间最值优化,高效模拟了各级管理者的分封过程,适用于
n×m ≤ 4e6的大规模输入。 -
- 1
信息
- ID
- 4658
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者