Official
B - 最長の登り坂 / Longest Uphill Editorial by admin
gpt-5.3-codex概要
配列 \(A\) の中で、連続する区間がずっと \(A_i \leq A_{i+1}\) を満たすような「最長の非減少連続部分列(連続区間)」の長さを求める問題です。
左から1回見るだけで、現在の登り坂の長さを更新していけば解けます。
考察
まず「登り坂」は連続区間であることが重要です。
つまり、ある地点で条件 \(A_i \leq A_{i+1}\) が壊れたら、その先は新しい登り坂を作り直すしかありません。
重要な気づき
- 今見ている地点 \(a\) と1つ前の地点
prevを比較すれば、
prev <= aなら今の登り坂を延長できる- そうでなければ登り坂は途切れるので長さを1にリセット
- 各時点で「今の登り坂の長さ
cur_len」と「これまでの最大ans」を持てば十分です。
素朴解が厳しい理由
例えば各始点 \(l\) から右へ伸ばして最長を調べる、という方法だと最悪で
\(1 + 2 + \cdots + N = O(N^2)\)
になります。\(N \le 10^5\) なので間に合いません。
解決策
配列を左から1回だけ走査して、隣接2要素の比較結果で cur_len を更新します。
これなら各要素を1回ずつ処理するだけなので高速です。
アルゴリズム
- \(N\) を読む。
- 最初の標高を
prevとして読む。 cur_len = 1,ans = 1で初期化。- 残り \(N-1\) 個の標高
aについて順に:- もし
prev <= aならcur_len += 1 - そうでなければ
cur_len = 1 ans = max(ans, cur_len)prev = aに更新
- もし
ansを出力。
具体例
\(A = [2, 2, 5, 3, 4, 4]\) のとき
- \(2 \to 2\) : 伸びる (cur=2)
- \(2 \to 5\) : 伸びる (cur=3)
- \(5 \to 3\) : 途切れる (cur=1)
- \(3 \to 4\) : 伸びる (cur=2)
- \(4 \to 4\) : 伸びる (cur=3)
最大は 3 です。
計算量
- 時間計算量: \(O(N)\)
- 空間計算量: \(O(1)\)
実装のポイント
入力が多いので
sys.stdin.readlineを使うと安全です。N=1のときも、初期値cur_len=ans=1で正しく処理できます。条件は「広義単調増加」なので比較は
<ではなく<=です。ソースコード
import sys
def main():
input = sys.stdin.readline
N = int(input().strip())
prev = int(input().strip())
cur_len = 1
ans = 1
for _ in range(1, N):
a = int(input().strip())
if prev <= a:
cur_len += 1
else:
cur_len = 1
if cur_len > ans:
ans = cur_len
prev = a
print(ans)
if __name__ == "__main__":
main()
この解説は gpt-5.3-codex によって生成されました。