The longest non-decreasing subsequence of an array...

Created on: June 17, 2025

Answered using O4 Mini High by Chat01

Question

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)

Thought

The user wants a dynamic programming solution on the Longest Non-Decreasing Subsequence (LNDS) with specific constraints. They ask for the problem to be solved in Java, using an O(n²) approach instead of the more efficient O(n log n). I think this means focusing on iterating through each possible prefix and checking earlier elements. The solution will involve maintaining a DP table and ensuring that the values from the specific range constraints are respected. I'll write it in Java with that in mind.

The user wants Java code to solve a problem using dynamic programming, where we need to compute the maximum length of the Longest Non-Decreasing Subsequence (LNDS) for each prefix length kk using given intervals lil_i and rir_i. The task is to choose values within those ranges to maximize the subsequence, ensuring the selected values form a non-decreasing sequence based on overlap conditions of intervals. We'll focus on selecting values that follow these constraints and compute the resulting LNDS for each prefix.

The user has suggested focusing on an O(n²) approach instead of an O(n log n) one, even though a naive DP solution with O(n²) may be too slow given the constraint of n2×105n \leq 2 \times 10^5. This makes me question if the user is testing code writing rather than focusing on performance. Perhaps the O(n²) is acceptable for smaller inputs or specific test cases. Given their instructions, I’ll proceed with a basic O(n²) DP implementation as requested, though more efficient solutions are possible.

The user wants a Java implementation for the problem using a simpler O(n²) dynamic programming (DP) approach over more complex solutions. The task involves finding the length of the longest subsequence, where each element is chosen from an interval range that satisfies certain conditions. It becomes tricky because the subsequence’s choice depends on interval overlaps, choosing the smallest possible value to maximize extendability. However, the user specifically requests the simpler O(n²) DP solution rather than a more optimized method like segment trees. I'll follow that direction.

Thought for 35 seconds

Answer

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.

java
import 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

  • We keep an array tail[] where tail[len] is the smallest possible last value of any non-decreasing subsequence of length len found so far.
  • Initially, tail[0] = -∞ (so we can always start a new subsequence) and all other tail[len] = +∞.
  • When we see a new interval [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.
    • The condition tail[len-1] ≤ r[j] ensures there exists some value in the previous subsequence’s tail that is ≤ some value in the new interval.
    • If so, the best new tail for a subsequence of length len becomes max(tail[len-1], l[j]) (the smallest feasible “next” value you can pick).
    • We update tail[len] if this gives a smaller tail, and update our global maxLen.
  • After processing interval j, maxLen is the maximum length achievable on the prefix of size j+1, and we record that in ans[j].
  • Total time per test is Θ(n²), which matches the requested approach.

Share this Q&A