Can you reach A certain mountain range has N N mo...
Créé le : 26 mars 2025
Créé le : 26 mars 2025
1
∣H
i
−H
i−1
∣=1 for every
i
i.
On each mountain peak lives a single person.
A person can move from one mountain peak to an adjacent mountain peak (i.e. a person standing on the
i
i-th peak can move to
i
−
1
i−1 or
i
+
1
i+1).
However, they will refuse to move to a mountain that's of the same height as one that has been visited before.
For example, if the heights are
[
1
,
2
,
3
,
2
,
3
]
[1,2,3,2,3], the person who is initially on the first peak can move to the second and third peaks, but will not move to the fourth (since it has a height of
2
2, which has already been visited along the way).
Similarly, the person initially on the fourth peak can move to the third or the fifth peak, but will not move to the second peak, since it has a height of
2
2 which is the same as the starting height.
Two people are considered to have a friendship between them if they can both reach the same mountain via some sequence of moves.
In the above example of
[
1
,
2
,
3
,
2
,
3
]
[1,2,3,2,3], the people on mountains
2
2 and
3
3 are friends (person
2
2 can move to mountain
3
3), and the people on mountains
1
1 and
4
4 are also friends (they can both move to mountain
3
3). However, the people on mountains
1
1 and
5
5 are not friends, because there's no common mountain where they can meet.
Given the heights of the mountain peaks, find the number of friendships.
Input Format
The first line of input will contain a single integer
T
T, denoting the number of test cases.
Each test case consists of two lines of input.
The first line of each test case contains one integer
N
N — the number of mountain peaks.
The next line contains
N
N space-separated integers
H
1
,
H
2
,
…
,
H
N
H
1
,H
2
,…,H
N
, describing the mountain heights.
Output Format
For each test case, output on a new line a single integer: the number of friendships.
Constraints
1
≤
T
≤
1
0
5
1≤T≤10
5
1
≤
N
≤
2
⋅
1
0
5
1≤N≤2⋅10
5
1
∣H
i
−H
i−1
∣=1 for each
1
≤
i
<
N
1≤i<N
The sum of
N
N over all test cases won't exceed
2
⋅
1
0
5
2⋅10
5
.
Sample 1:
Input
Output
2
5
3 4 5 4 3
4
1 2 1 2
10
5
Explanation:
Test case
1
1: Every person is able to reach the highest mountain, i.e.
5
5. Since for every pair of people there's a mountain they can both reach, every pair of people will be friends.
Test case
2
2: The friendships are as follows:
Persons
1
1 and
2
2 are friends: they're already adjacent to each other so one of them can just move to the other.
Similarly
(
2
,
3
)
(2,3) and
(
3
,
4
)
(3,4) are friends.
Persons
1
1 and
3
3 are friends: they can both move to mountain
2
2 and meet there.
Similarly, persons
2
2 and
4
4 are friends, since they can meet at mountain
3
3.
However, there's no way for persons
1
1 and
4
4 to ever meet.
The total number of friendships is hence
5
5.
Did you like the problem statement?
More Info
Time limit1 secs
Memory limit1.5 GB
Source Limit50000 Bytes
import java.util.;
import java.lang.;
import java.io.*;
class Codechef
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
}
}
write a java solution
javaimport java.util.*; import java.io.*; /* We have an array of N mountain heights H[0..N-1], where |H[i] - H[i-1]| = 1. Each person starts on a distinct peak i and can move left or right, one step at a time, but may never step onto a height that has been visited before by that same traveler. Two people (at indices i and j) are "friends" if there is at least one peak k that both can reach (possibly by different paths). Equivalently, if the sets of reachable indices for i and j overlap. Key insight: • From a starting peak i, one can only ever walk strictly left or strictly right (because turning back would revisit a previously-used height). • Hence for each index i, define: L[i] = the leftmost index one can reach from i by walking only left. R[i] = the rightmost index one can reach from i by walking only right. Then the total set of indices a person at i can reach is [L[i] .. i] union [i .. R[i]], which is simply the interval [ L[i], R[i] ]. Therefore, person i and person j are friends if and only if their intervals [L[i], R[i]] and [L[j], R[j]] intersect. Once we have these intervals, the problem reduces to counting the number of intersecting pairs among N intervals. This is a standard line-sweep or "interval intersection" counting problem. Steps to solve each test case: 1) Read N and the array H of length N. 2) Compute R[i] for each i via a standard "two-pointer" scan from left to right, ensuring [i..R[i]] is the maximal subarray with distinct heights. 3) Compute L[i] similarly by scanning from right to left, ensuring [L[i]..i] is a maximal subarray with distinct heights. 4) Form intervals[i] = (L[i], R[i]) for i in [0..N-1]. 5) Sort these intervals by their left endpoint (ascending). Also have a sort by their right endpoint (ascending). Use a two-pointer sweep to count how many pairs of intervals intersect. Complexity: - Computing L and R each takes O(N) via two-pointer + frequency array. - Sorting intervals takes O(N log N). - Counting intersections with a sweep is O(N) after sorting. - Summed over all test cases, ∑N ≤ 2×10^5, so this is efficient enough. */ class Codechef { static FastReader in = new FastReader(); static PrintWriter out = new PrintWriter(System.out,false); public static void main(String[] args) { int T = in.nextInt(); // We will process each test independently. // The sum of N over all T does not exceed 2e5, so this approach is feasible. while(T-- > 0){ solveOneTest(); } out.close(); } static void solveOneTest(){ int N = in.nextInt(); int[] H = new int[N]; for(int i=0; i<N; i++){ H[i] = in.nextInt(); } // Edge case: if N=1, answer is 0 because there is only 1 person. if(N == 1){ out.println(0); return; } // 1) Compute R array via two-pointer from left to right. int[] R = new int[N]; int[] freq = new int[N+1]; // heights up to N (per constraints) int r = 0; for(int i=0; i<N; i++){ while(r < N && freq[ H[r] ] == 0){ freq[ H[r] ] = 1; r++; } // Now r is the first index we cannot include. So [i..r-1] is distinct. R[i] = r - 1; // Remove H[i] from the frequency as we move left pointer from i to i+1 freq[ H[i] ] = 0; } // 2) Compute L array via two-pointer from right to left. int[] L = new int[N]; Arrays.fill(freq, 0); int l = N-1; for(int i=N-1; i>=0; i--){ while(l >= 0 && freq[ H[l] ] == 0){ freq[ H[l] ] = 1; l--; } // Now l is the first index we cannot include from the left side. // So [l+1 .. i] is distinct. L[i] = l + 1; freq[ H[i] ] = 0; } // 3) Build intervals [L[i], R[i]]. // We'll store them in 0-based form. // We'll count how many pairs of intervals intersect. int[][] intervals = new int[N][2]; for(int i=0; i<N; i++){ intervals[i][0] = L[i]; intervals[i][1] = R[i]; } // 4) Count intersections using a standard sweep: // Sort once by "left" and separately by "right". Then for each interval // in ascending order of left, remove from "active" all intervals whose // right < current_left. The number of intervals still active is the // count of intervals that intersect with the current one. // Add that to our sum, then add the current interval to active. // This counts each intersecting pair (i < j) exactly once. // Create index arrays for sorting by left and by right Integer[] idxL = new Integer[N]; Integer[] idxR = new Integer[N]; for(int i=0; i<N; i++){ idxL[i] = i; idxR[i] = i; } Arrays.sort(idxL, (a,b) -> Integer.compare(intervals[a][0], intervals[b][0])); Arrays.sort(idxR, (a,b) -> Integer.compare(intervals[a][1], intervals[b][1])); long friendshipCount = 0L; int active = 0; // how many intervals are currently "active" int rPtr = 0; // pointer on the array sorted by right for(int jPtr=0; jPtr<N; jPtr++){ int j = idxL[jPtr]; int leftJ = intervals[j][0]; // L(j) // Remove from active all intervals that ended before leftJ while(rPtr < N && intervals[idxR[rPtr]][1] < leftJ){ active--; rPtr++; } // All intervals still active now must intersect with j friendshipCount += active; // Now add the j-th interval to active set active++; } out.println(friendshipCount); } // A fast input reader (often needed in Java for large-input problems). static class FastReader { BufferedReader br; StringTokenizer st; public FastReader(){ br = new BufferedReader(new InputStreamReader(System.in)); } String next(){ while(st == null || !st.hasMoreElements()){ try{ String line = br.readLine(); if(line == null) return null; st = new StringTokenizer(line); }catch(IOException e){ throw new RuntimeException(e); } } return st.nextToken(); } int nextInt(){ return Integer.parseInt(next()); } } }
Explanation of the core ideas:
Distinct-heights subarrays from each index i.
We first find, for each i, the maximal right endpoint R[i] such that the subarray H[i..R[i]] has no repeated heights.
This can be done in O(N) with a classic two-pointer "sliding window" over distinct elements.
Similarly, we find the maximal left endpoint L[i] such that H[L[i]..i] is distinct, by running an analogous procedure from right to left.
Once we have (L[i], R[i]) for each i, the set of indices that i can possibly stand on (via some one-direction walk) is the entire interval [L[i], R[i]]. Two travelers i and j can meet if and only if their intervals [L[i], R[i]] and [L[j], R[j]] intersect.
Counting the number of intersecting interval-pairs is a standard sweep-line problem. Sort intervals by left endpoint, and maintain a pointer over the (separately) right-sorted list to discard intervals that have already "ended."
This yields the required total number of friendships.