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.
accepted
Accepted
51
total-Submissions
Submissions
63
accuracy
Accuracy
80.95
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
Analysis
We are given mountain peaks in a line, each with a height . Adjacent heights differ by exactly 1, i.e.\ . On each peak there is one person.
A person at peak can move step‐by‐step to adjacent peaks, but is never allowed to set foot on a height that has been visited before in that path. Equivalently, the path of visited heights must contain no repeats. Because each adjacent step changes the height by , one can show:
A valid path (with no repeated heights) must be strictly monotonic in index order—i.e.\ it cannot change “direction” (from going up to going down, or vice versa) without immediately revisiting a height.
Hence, from a given peak , that person can only:
• move left along a run of strictly increasing or strictly decreasing heights (but not turn around), or
• move right along a run of strictly increasing or strictly decreasing heights (but not turn around), or
• stay put.
Because we only need the possibility of moving along such a path, effectively each index has two “maximal intervals of reach”: one to the left, one to the right, depending on whether the heights step up or down. Merging those two one‐sided intervals (which overlap at ) gives a single “reach interval” .
Two people and are friends exactly if their reach‐intervals intersect:
Therefore, the problem reduces to:
Step 2 is a classical “count the number of intersecting‐interval pairs” problem, which can be done in via a standard sweep‐line or two‐pointer approach.
Because the sum of all over all testcases is at most , an solution per test is acceptable overall.
Read input. For each test:
Edge case: If , there are no pairs, so answer is 0 immediately.
Build the “direction” array of length , where
(All differences are .)
Precompute “maximal run” boundaries going left and right:
upLeft[]
and downLeft[]
, which say:upLeft[i]
is how far left we can extend maintaining +1 steps.downLeft[i]
is how far left we can extend with -1 steps.”upRight[]
and downRight[]
by going right‐to‐left.Concretely (1-based indexing):
Assign each index a single interval which is the (union of) the left and right runs, but they always overlap at , so it becomes a single continuous interval:
So the person at peak can reach exactly the integer indices in .
Count intersecting‐interval pairs. Each person has interval . We want how many have
A standard sweep‐line in ascending order of “start” works:
That total is our answer for the test.
javaimport java.util.*; import java.io.*; class Codechef { static FastInput in = new FastInput(System.in); static PrintWriter out = new PrintWriter(System.out,false); public static void main(String[] args) { int T = in.nextInt(); while (T-- > 0) { int N = in.nextInt(); int[] H = new int[N]; for(int i=0; i<N; i++){ H[i] = in.nextInt(); } // Edge case: N=1 => no pairs if(N<=1){ out.println(0); continue; } // Build D array: D[i] = +1 if H[i+1]>H[i], -1 otherwise // 1-based logic means D[i] = sign(H[i+1]-H[i]) for i=1..(N-1), but let's keep 0-based in code int[] D = new int[N-1]; for(int i=0; i<N-1; i++){ D[i] = (H[i+1] > H[i])? +1 : -1; } // upLeft[i], downLeft[i] (1-based concept, but we'll do 0-based in code): int[] upLeft = new int[N]; int[] downLeft = new int[N]; upLeft[0] = 0; downLeft[0] = 0; for(int i=1; i<N; i++){ if(D[i-1]== +1){ // continue up run upLeft[i] = upLeft[i-1]; } else { upLeft[i] = i; } if(D[i-1]== -1){ // continue down run downLeft[i] = downLeft[i-1]; } else { downLeft[i] = i; } } // upRight[i], downRight[i] int[] upRight = new int[N]; int[] downRight = new int[N]; upRight[N-1] = N-1; downRight[N-1] = N-1; for(int i=N-2; i>=0; i--){ if(D[i]== +1){ upRight[i] = upRight[i+1]; } else { upRight[i] = i; } if(D[i]== -1){ downRight[i] = downRight[i+1]; } else { downRight[i] = i; } } // Build intervals [L[i], R[i]] for each i in 0..N-1 // Converting the 1-based formula to 0-based carefully: // L[i] = if i==0 => 0 // else if D[i-1]==+1 => upLeft[i] // else => downLeft[i] // R[i] = if i==N-1 => N-1 // else if D[i]==+1 => upRight[i] // else => downRight[i] // and each person's final interval is inclusive, over indices 0..N-1. long[][] intervals = new long[N][2]; // each row: [start, end] for(int i=0; i<N; i++){ // Compute L[i] int L; if(i==0){ L = 0; } else { if(D[i-1]== +1){ L = upLeft[i]; } else { L = downLeft[i]; } } // Compute R[i] int R; if(i==N-1){ R = N-1; } else { if(D[i]== +1){ R = upRight[i]; } else { R = downRight[i]; } } intervals[i][0] = L; // start intervals[i][1] = R; // end } // Now count how many pairs (i,j) have intervals overlapping // We'll do a standard sweep by "start" Arrays.sort(intervals, (a,b) -> { if(a[0]<b[0]) return -1; else if(a[0]>b[0]) return +1; // tie => compare end if(a[1]<b[1]) return -1; else if(a[1]>b[1]) return +1; return 0; }); // Sweep line: for each interval in ascending start, // pop from a min-heap all intervals whose end < current.start, // then add the current interval's end to the heap // number of intervals left in the heap is how many we intersect with PriorityQueue<Long> minHeap = new PriorityQueue<>(); long count = 0L; for(int i=0; i<N; i++){ long start = intervals[i][0]; long end = intervals[i][1]; // pop all intervals that ended before 'start' while(!minHeap.isEmpty() && minHeap.peek()<start){ minHeap.poll(); } // all intervals left are those that end >= start => they intersect count += minHeap.size(); // now add this interval's end minHeap.offer(end); } out.println(count); } out.flush(); } // A simple fast input helper (not strictly required, but often helpful in large IO): static class FastInput { private final BufferedInputStream buf; private int bId = 0, size = 0; private byte[] buffer = new byte[1<<16]; FastInput(InputStream in) { buf = new BufferedInputStream(in); } private byte read() { if(bId==size){ try { size = buf.read(buffer); } catch(IOException e){ throw new RuntimeException(e); } if(size==-1) return -1; bId=0; } return buffer[bId++]; } private boolean isSpace(byte c){return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;} int nextInt() { int sign=1; byte c=read(); while(isSpace(c)) c=read(); if(c=='-'){ sign=-1; c=read(); } int val=0; while(!isSpace(c)){ if(c<'0'||c>'9') throw new RuntimeException("Unexpected character "+(char)c); val=val*10+(c-'0'); c=read(); } return val*sign; } } }
Explanation of the key steps:
• We transform the “cannot revisit heights” rule into “any valid walk must be strictly monotonic in index order.”
• From each index i, we figure out how far left we can go (without changing +1/−1 direction) and how far right likewise. Merging them gives one continuous interval [Lᵢ, Rᵢ].
• Two indices i, j can meet if and only if [Lᵢ, Rᵢ] intersects [Lⱼ, Rⱼ].
• We then do a standard counting of intersecting intervals via sorting and a min‐heap.
This solves the problem in O(N log N) time per test, which is efficient for the given constraints.