#19282. 秦始皇兵马俑

秦始皇兵马俑

你好!我是你的OI金牌教练。

我们已经练习了数组和区间的各种线性操作(前缀和、差分、双指针)。今天,我们穿越回中国历史上第一个大一统王朝——秦朝,结合世界八大奇迹之一的**“秦始皇陵兵马俑”,来讲解一种非常重要的线性数据结构算法**——单调栈 (Monotonic Stack)

这道题目符合 GESP 6级 难度,考察如何在 O(N)O(N) 的时间复杂度内解决“寻找第一个比自己大/小的元素”这类问题。


第一部分:背景知识讲解

1. 秦始皇陵兵马俑 (The Terracotta Army)

秦始皇陵位于陕西省西安市,其陪葬坑中出土了成千上万个陶制兵马俑。这些兵马俑面部神态各异,排列成严整的军阵,重现了秦军统一六国时的雄风。

2. 军阵与视野

在古代军阵中,士兵的排列非常讲究。为了保持阵型整齐并便于指挥,通常要求士兵视线能够穿过前方或侧方较矮的战友,看到军旗或指挥官。 如果一个士兵的右侧站着一个比他的战友,他的视线就会被遮挡;反之,如果右侧的战友都比他矮,他就能看得更远。

3. 算法痛点

假设有 NN 个士兵排成一列。对于每一个士兵,我们想知道:站在他右边、且第一个比他高的士兵是谁?

  • 暴力法:对于第 ii 个士兵,向右遍历 i+1Ni+1 \dots N,找到第一个大于 HiH_i 的。复杂度 O(N2)O(N^2)。当 N=106N=10^6 时会超时。
  • 单调栈:一种利用“栈”的后进先出特性,在遍历过程中维护一个单调递减(或递增)序列,从而实现 O(N)O(N) 解决问题的技巧。

第二部分:题目内容

题目名称:兵马俑的军阵 (The Formation of Terracotta Warriors)

题目描述

考古学家在秦始皇陵发现了一排刚刚出土的兵马俑。这排兵马俑共有 NN 个,从左到右依次编号为 11NN。 通过测量,第 ii 号兵马俑的高度为 HiH_i

为了研究秦军的列阵规律,考古学家定义了一个**“仰视目标”的概念: 对于第 ii 号兵马俑,他的“仰视目标”是他右侧**(编号大于 ii)的兵马俑中,第一个高度严格大于 HiH_i 的兵马俑的编号。 如果右侧没有比他高的兵马俑,则他的“仰视目标”为 00

请你编写程序,快速计算出这 NN 个兵马俑每一个人的“仰视目标”编号。

输入格式

第一行包含一个正整数 NN,表示兵马俑的数量。

第二行包含 NN 个正整数 H1,H2,,HNH_1, H_2, \dots, H_N,表示从左到右每个兵马俑的高度。

输出格式

输出一行,包含 NN 个整数,第 ii 个整数表示第 ii 号兵马俑的“仰视目标”编号。整数之间用空格隔开。

输入输出样例 #1

输入:

5
5 3 1 2 4

输出:

0 5 4 5 0

样例 #1 解释:

  • 1号 (高度5):右边是 3, 1, 2, 4,没有比 5 高的。输出 0
  • 2号 (高度3):右边是 1, 2, 4
    • 1 < 3
    • 2 < 3
    • 4 > 3 -> 找到了!编号是 5
  • 3号 (高度1):右边是 2, 4
    • 2 > 1 -> 找到了!编号是 4
  • 4号 (高度2):右边是 4
    • 4 > 2 -> 找到了!编号是 5
  • 5号 (高度4):右边没人。输出 0

结果:0 5 4 5 0

输入输出样例 #2

输入:

6
10 9 8 7 6 11

输出:

6 6 6 6 6 0

样例 #2 解释: 前面 1~5 号虽然高度递减,但他们右边都有一个 6 号(高度11),11 是他们右边第一个比自己大的(也是唯一一个比自己大的)。 6 号右边没人,输出 0。

数据范围

对于 100%100\% 的数据:

  • 1N1061 \le N \le 10^6
  • 1Hi1091 \le H_i \le 10^9
  • 建议使用 O(N)O(N) 的算法,否则可能会超时。