The longest non-decreasing subsequence of an array...
Created on: June 17, 2025
Answered using O4 Mini High by Chat01
Created on: June 17, 2025
Answered using O4 Mini High by Chat01
The longest non-decreasing subsequence of an array of integers a1,a2,…,an
is the longest sequence of indices 1≤i1<i2<…<ik≤n
such that ai1≤ai2≤…≤aik
. The length of the sequence is defined as the number of elements in the sequence. For example, the length of the longest non-decreasing subsequence of the array a=[3,1,4,1,2]
is 3
.
You are given two arrays of integers l1,l2,…,ln
and r1,r2,…,rn
. For each 1≤k≤n
, solve the following problem:
Consider all arrays of integers a
of length k
, such that for each 1≤i≤k
, it holds that li≤ai≤ri
. Find the maximum length of the longest non-decreasing subsequence among all such arrays.
Input
Each test consists of multiple test cases. The first line contains a single integer t
(1≤t≤104
) — the number of test cases. The description of the test cases follows.
The first line of each test case contains a single integer n
(1≤n≤2⋅105
) — the length of the arrays l
and r
.
The next n
lines of each test case contain two integers li
and ri
(1≤li≤ri≤109
).
It is guaranteed that the sum of n
across all test cases does not exceed 2⋅105
.
Output
For each test case, output n
integers: for each k
from 1
to n
, output the maximum length of the longest non-decreasing subsequence among all suitable arrays.
Example
InputCopy
6
1
1 1
2
3 4
1 2
4
4 5
3 4
1 3
3 3
8
6 8
4 6
3 5
5 5
3 4
1 3
2 4
3 3
5
1 2
6 8
4 5
2 3
3 3
11
35 120
66 229
41 266
98 164
55 153
125 174
139 237
30 72
138 212
109 123
174 196
OutputCopy
1
1 1
1 2 2 3
1 2 2 3 3 3 4 5
1 2 2 2 3
1 2 3 4 5 6 7 7 8 8 9
Note
In the first test case, the only possible array is a=[1]
. The length of the longest non-decreasing subsequence of this array is 1
.
In the second test case, for k=2
, no matter how we choose the values of a1
and a2
, the condition a1>a2
will always hold. Therefore, the answer for k=2
will be 1
.
In the third test case, for k=4
, we can choose the array a=[5,3,3,3]
. The length of the longest non-decreasing subsequence of this array is 3
.
In the fourth test case, for k=8
, we can choose the array a=[7,5,3,5,3,3,3,3]
. The length of the longest non-decreasing subsequence of this array is 5
.
In the fifth test case, for k=5
, we can choose the array a=[2,8,5,3,3]
. The length of the longest non-decreasing subsequence of this array is 3
.
code this in java
I think you can now focus on O(n^2) approach instead of O(nlog n)
Here’s a straightforward O(n²) Java solution using the classic “tails” DP for non-decreasing subsequences extended to intervals. For each prefix k it runs a backward scan to update the smallest possible tail value for every subsequence length and thus keeps track of the maximum length seen so far.
javaimport java.io.*; import java.util.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out))); int t = Integer.parseInt(br.readLine().trim()); final int NEG_INF = Integer.MIN_VALUE; final int INF = Integer.MAX_VALUE; while (t-- > 0) { int n = Integer.parseInt(br.readLine().trim()); int[] l = new int[n]; int[] r = new int[n]; for (int i = 0; i < n; i++) { StringTokenizer st = new StringTokenizer(br.readLine()); l[i] = Integer.parseInt(st.nextToken()); r[i] = Integer.parseInt(st.nextToken()); } // tail[len] = minimal possible last value of a non-decreasing subsequence of length len int[] tail = new int[n + 2]; Arrays.fill(tail, INF); tail[0] = NEG_INF; int maxLen = 0; int[] ans = new int[n]; for (int j = 0; j < n; j++) { // try to extend every existing subsequence of length len-1 to length len using interval j for (int len = j + 1; len >= 1; len--) { if (tail[len - 1] <= r[j]) { int newTail = Math.max(tail[len - 1], l[j]); if (newTail < tail[len]) { tail[len] = newTail; } if (len > maxLen) { maxLen = len; } } } ans[j] = maxLen; } // output answers for k = 1..n for (int i = 0; i < n; i++) { out.print(ans[i]); if (i + 1 < n) out.print(' '); } out.println(); } out.flush(); } }
How it works
tail[]
where tail[len]
is the smallest possible last value of any non-decreasing subsequence of length len
found so far.tail[0] = -∞
(so we can always start a new subsequence) and all other tail[len] = +∞
.[l[j], r[j]]
, we scan len
from j+1
down to 1
and check if we can extend a subsequence of length len-1
.
tail[len-1] ≤ r[j]
ensures there exists some value in the previous subsequence’s tail that is ≤ some value in the new interval.len
becomes max(tail[len-1], l[j])
(the smallest feasible “next” value you can pick).tail[len]
if this gives a smaller tail, and update our global maxLen
.j
, maxLen
is the maximum length achievable on the prefix of size j+1
, and we record that in ans[j]
.