E - 山道のハイキングコース / Hiking Course on a Mountain Trail Editorial by admin
gpt-5.5-highOverview
The post-maintenance elevation sequence that satisfies the condition is a “mountain path” where adjacent elevations must change by exactly \(1\). We want to choose a subset of checkpoints to keep at their original elevations, convert the condition of whether this subset is simultaneously realizable into a manageable form, and find the maximum number of checkpoints we can keep.
Analysis
First, let’s consider keeping both of two checkpoints \(i < j\) as they are.
To match the code, we will assume 0-indexed positions.
Letting their elevations be \(H_i\) and \(H_j\), there are \(j-i\) steps between \(i\) and \(j\).
Since the difference between adjacent elevations must be exactly \(1\), the conditions for being able to reach \(H_j\) from \(H_i\) in \(j-i\) steps are the following two:
The difference in height is at most the number of steps:
$\( |H_i - H_j| \le j-i \)$The parities match:
Since we perform \(\pm 1\) a total of \(j-i\) times, the parity of the height flips with each step.
Therefore, $\( (i + H_i) \bmod 2 = (j + H_j) \bmod 2 \)$
Here, we apply the following transformation:
\[ x_i = i + H_i \]
\[ y_i = i - H_i \]
Then, the condition \(|H_i - H_j| \le j-i\) can be decomposed into the following two:
\[ H_i - H_j \le j-i \]
This is
\[ i + H_i \le j + H_j \]
which means
\[ x_i \le x_j \]
Also,
\[ H_j - H_i \le j-i \]
This is
\[ i - H_i \le j - H_j \]
which means
\[ y_i \le y_j \]
Therefore, when looking only at points with the same parity, the checkpoints we can keep form a sequence that satisfies both \(x_i \le x_j\) and \(y_i \le y_j\), which is a monotonically increasing sequence in 2D space.
A naive search of “which checkpoints to keep” would take \(2^N\) combinations, which is far too slow.
Also, DP with elevations as states is impossible since \(H_i \le 10^9\).
Thus, we can convert each checkpoint to \((x_i, y_i)\), divide them by parity, and find the “Longest Non-Decreasing Subsequence (LNDS) of \(y\) when sorted in ascending order of \(x\)”.
Here, it is important that the subsequence is “non-decreasing”.
If \(y\) is equal, the condition \(y_i \le y_j\) is still satisfied, so they can be kept simultaneously.
Algorithm
- For each checkpoint \(i\), compute the following:
$\( x = i + H_i \)$
$\( y = i - H_i \)$
Divide them into two groups based on the parity of \(x\), i.e., \((i + H_i) \bmod 2\).
For each group, sort the points \((x, y)\) in ascending order of \(x\).
Find the Longest Non-Decreasing Subsequence (LNDS) for the sorted sequence of \(y\).
In Python, you can find the non-decreasing subsequence by using bisect_right.
pos = bisect_right(tails, v)
tails[k] represents “the minimum possible value of the end of a non-decreasing subsequence of length \(k+1\)”.
- The maximum of the LNDS lengths of the two parity groups is the answer.
Complexity
- Time Complexity: \(O(N \log N)\)
- Space Complexity: \(O(N)\)
Implementation Points
The position \(i\) is treated as 0-indexed in the code using
enumerate(H).Checkpoints with different \((i + H_i) \bmod 2\) cannot be kept at the same time, so they must be separated into different groups.
Since the condition is \(y_i \le y_j\), we need the LNDS (Longest Non-Decreasing Subsequence) instead of the LIS (Longest Increasing Subsequence). Therefore, we use
bisect_rightinstead ofbisect_left.\(y = i - H_i\) can be negative, but this is not an issue since it is only used for sorting and comparison.
Source Code
import sys
from bisect import bisect_right
def main():
data = list(map(int, sys.stdin.buffer.read().split()))
N = data[0]
H = data[1:]
groups = [[], []]
for i, h in enumerate(H):
groups[(i + h) & 1].append((i + h, i - h))
ans = 0
for g in groups:
g.sort()
tails = []
for _, v in g:
pos = bisect_right(tails, v)
if pos == len(tails):
tails.append(v)
else:
tails[pos] = v
ans = max(ans, len(tails))
print(ans)
if __name__ == "__main__":
main()
This editorial was generated by gpt-5.5-high.