CSES Solutions Nested Ranges Check (original) (raw)

Last Updated : 10 Jul, 2024

Given **N ranges, the task is to determine for each range if it contains some other range and if some other range contains it. Range [a,b] contains range [c,d] if a ≤ c and d ≤ b. First print a line that describes for each range (in the input order) if it contains some other range (1) or not (0). Then print a line that describes for each range (in the input order) if some other range contains it (1) or not (0).

Example:

**Input: N=4, range[]={{1, 6}, {2, 4}, {4, 8}, {3, 6}}
**Output:
1 0 0 0
0 1 0 1
**Explanation: The first line of the output (1 0 0 0) indicates whether each range contains some other range or not.

The second line of the output (0 1 0 1) indicates whether each range is contained by some other range or not.

**Input: N=4, range[]={{2, 7}, {3, 5}, {1, 8}, {4, 6}}
**Output:
1 0 1 0
1 1 0 1
**Explanation: The first line of the output (1 0 1 0) indicates whether each range contains some other range or not.

The second line of the output (1 1 0 1) indicates whether each range is contained by some other range or not.

**Approach: To solve the problem, follow the idea below:

The idea is to sort the ranges in ascending order based on their left end. If two ranges have the same left end, prioritize the one with the larger right end. Now, we only need to check the right end for both operations:

For the “contains” operation:

For the “contained” operation:

Below is the implementation of above algorithm:

C++ `

// C++ Code for CSES - Nested Ranges Check #include <bits/stdc++.h> using namespace std;

// struct to hold the range information struct ranges { // The left and right ends of the range and its index in // the input order int l, r, in;

// Overloads the < operator for sorting
bool operator<(const ranges& other) const
{
    // If left ends are equal, the range with larger
    // right end comes first
    if (l == other.l)
        return r > other.r;
    // Otherwise, the range with smaller left end comes
    // first
    return l < other.l;
}

};

// Function to determine for each range if it contains some // other range and if some other range contains it. vector<vector > checkrange(vector<vector >& r, int n) { vector range(n); vector contains(n), contained(n);

for (int i = 0; i < n; i++) {
    range[i].l = r[i][0];
    range[i].r = r[i][1];
    range[i].in = i;
}

// Sorts the ranges
sort(range.begin(), range.end());

// Checks if a range contains another
int minEnd = 2e9;
for (int i = n - 1; i >= 0; i--) {
    // If the right end of the current range is greater
    // than minEnd, it contains another
    if (range[i].r >= minEnd)
        contains[range[i].in] = 1;

    // Update minEnd
    minEnd = min(minEnd, range[i].r);
}

// Checks if a range is contained by another
int maxEnd = 0;
for (int i = 0; i < n; i++) {
    // If the right end of the current range is less
    // than maxEnd, it is contained by another
    if (range[i].r <= maxEnd)
        contained[range[i].in] = 1;

    // Update maxEnd
    maxEnd = max(maxEnd, range[i].r);
}

// Returns the contains and contained vector
return { contains, contained };

}

// Driver code int main() { int n = 4; // Example 1 vector<vector > r = { { 1, 6 }, { 2, 4 }, { 4, 8 }, { 3, 6 } }; vector<vector > res = checkrange(r, n); for (int i = 0; i < 2; i++) { for (int j = 0; j < n; j++) cout << res[i][j] << " "; cout << endl; } return 0; }

`

**Time Complexity: O(N*log(N)), where **N is the size of the range.
**Auxiliary Space: O(N)