Can you reach A certain mountain range has N N mo...
생성일: 2025년 3월 26일
생성일: 2025년 3월 26일
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.lang.*; import java.io.*; class Codechef { // Fast IO helper static class FastReader { final private int BUFFER_SIZE = 1 << 16; private DataInputStream din; private byte[] buffer; private int bufferPointer, bytesRead; public FastReader() { din = new DataInputStream(System.in); buffer = new byte[BUFFER_SIZE]; bufferPointer = bytesRead = 0; } public FastReader(String file_name) throws IOException { din = new DataInputStream(new FileInputStream(file_name)); buffer = new byte[BUFFER_SIZE]; bufferPointer = bytesRead = 0; } public String nextLine() throws IOException { byte[] buf = new byte[100000]; // string length int cnt = 0, c; while ((c = read()) != -1) { if (c == '\n') { if (cnt != 0) break; else continue; } buf[cnt++] = (byte) c; } return new String(buf, 0, cnt); } public int nextInt() throws IOException { int ret = 0; byte c = read(); while (c <= ' ') c = read(); boolean neg = (c == '-'); if (neg) c = read(); do { ret = ret * 10 + c - '0'; } while ((c = read()) >= '0' && c <= '9'); if (neg) return -ret; return ret; } public long nextLong() throws IOException { long ret = 0; byte c = read(); while (c <= ' ') c = read(); boolean neg = (c == '-'); if (neg) c = read(); do { ret = ret * 10 + c - '0'; } while ((c = read()) >= '0' && c <= '9'); if (neg) return -ret; return ret; } private byte read() throws IOException { if (bufferPointer == bytesRead) fillBuffer(); return buffer[bufferPointer++]; } private void fillBuffer() throws IOException { bytesRead = din.read(buffer, 0, BUFFER_SIZE); if (bytesRead == -1) buffer[0] = -1; bufferPointer = 0; } public void close() throws IOException { if (din == null) return; din.close(); } } static class Interval { int L, R; Interval(int l, int r) { this.L = l; this.R = r; } } public static void main (String[] args) throws java.lang.Exception { FastReader in = new FastReader(); int T = in.nextInt(); // We will reuse arrays up to the maximum possible N across all testcases // per the problem constraint sum(N) <= 2*10^5. // But for clarity, we'll just allocate anew for each test. That is fine too. StringBuilder out = new StringBuilder(); while(T-- > 0) { int N = in.nextInt(); int[] H = new int[N]; for(int i = 0; i < N; i++){ H[i] = in.nextInt(); } // If there is only one peak, there are no pairs of people at all. if(N <= 1) { out.append("0\n"); continue; } // 1) Compute L[i]: // L[i] = the smallest index ℓ such that the subarray H[ℓ..i] is distinct. int[] L = new int[N]; int[] lastOcc = new int[N+1]; Arrays.fill(lastOcc, -1); int start = 0; for(int i = 0; i < N; i++){ int h = H[i]; if(lastOcc[h] >= start){ start = lastOcc[h] + 1; } L[i] = start; lastOcc[h] = i; } // 2) Compute R[i]: // R[i] = the largest index r such that H[i..r] is distinct. int[] R = new int[N]; int[] nextOcc = new int[N+1]; Arrays.fill(nextOcc, -1); int end = N-1; for(int i = N-1; i >= 0; i--){ if(i > end) { end = i; } int h = H[i]; int p = nextOcc[h]; if(p != -1 && p <= end){ end = p - 1; } if(end < i){ end = i; // ensure valid subarray } R[i] = end; nextOcc[h] = i; } // 3) Build intervals [L[i], R[i]] for i in [0..N-1]. Interval[] intervals = new Interval[N]; for(int i = 0; i < N; i++){ intervals[i] = new Interval(L[i], R[i]); } // 4) Sort intervals by L ascending, then by R ascending Arrays.sort(intervals, new Comparator<Interval>() { public int compare(Interval a, Interval b) { if(a.L != b.L) return Integer.compare(a.L, b.L); return Integer.compare(a.R, b.R); } }); // 5) Count how many pairs of intervals do NOT intersect // We do a standard sweep: for each j, count how many i < j // have intervals[i].R < intervals[j].L. long countNonIntersect = 0; int p = 0; for(int j = 0; j < N; j++){ int Lj = intervals[j].L; while(p < j && intervals[p].R < Lj){ p++; } // All intervals from 0..(p-1) do not intersect with j countNonIntersect += p; } // Total pairs = N choose 2 long totalPairs = (long)N * (N - 1) / 2; long answer = totalPairs - countNonIntersect; out.append(answer).append("\n"); } System.out.print(out); } }
Explanation of the core idea:
For each position i (0-based) in the array H, we determine:
– L[i]: how far left we can go without repeating a height.
Concretely, L[i] is the smallest index ℓ ≤ i such that the subarray H[ℓ..i] is made of distinct heights.
This can be computed by a standard “last occurrence / sliding window” approach from left to right.
– R[i]: how far right we can go without repeating a height.
Concretely, R[i] is the largest index r ≥ i such that the subarray H[i..r] is made of distinct heights.
This can be computed analogously by scanning from right to left.
Intuitively, the set of peaks i can ever stand on (possibly via different paths) is exactly all j in the interval [L[i], R[i]].
Two people at peaks i and j are “friends” (i.e. can meet) if and only if their intervals [L[i], R[i]] and [L[j], R[j]] intersect.
Indeed, any common index in the intersection is a peak both can reach.
To count the number of intersecting‐interval pairs:
– Sort the intervals by their left endpoint L ascending (and R ascending on ties).
– Sweep through them in this sorted order, and for each interval “j” count how many intervals “i” (with i<j) lie completely to the left (i.e. whose R[i] < L[j]).
– Those form the non‐intersecting pairs. Summing these yields the count of non‐intersecting pairs.
– Subtract from the total number of pairs (N*(N-1)/2) to get the count of intersecting (i.e. “friends”) pairs.
This runs in O(N log N) time per test, mainly due to the sort. Since the sum of N across all tests is at most 2×10^5, the overall approach is efficient enough.