# Count of ways to select exactly K non-disjoint ranges from given N ranges

• Difficulty Level : Expert
• Last Updated : 04 Aug, 2022

Given two arrays L[] and R[] of size N, and an integer K, the task is to find the number of ways to select exact K disjoint ranges formed by taking elements present at the same index from the array L[] and R[].

Examples

Input: N = 7, K = 3, L[] = {1, 3, 4, 6, 1, 5, 8}, R[] = {7, 8, 5, 7, 3, 10, 9}
Output: 9
Explanation:
The possible ways of selecting K ranges are:

1. Select ranges {1, 7}, {3, 8}, and {4, 5}
2. Select ranges {1, 7}, {3, 8}, and {6, 7}
3. Select ranges {1, 7}, {3, 8}, and {1, 3}
4. Select ranges {1, 7}, {3, 8}, and {5, 10}
5. Select ranges {1, 7}, {4, 5}, and {5, 10}
6. Select ranges {1, 7}, {6, 7}, and {5, 10}
7. Select ranges {3, 8}, {4, 5}, and {5, 10}
8. Select ranges {3, 8}, {6, 7}, and {5, 10}
9. Select ranges {3, 8}, {5, 10}, and {8, 9}

Input: N = 2, K = 2, L[] = {100, 200}, R[] ={ 201, 300}
Output: 0

Naive Approach: The simplest approach to solve the problem is to select every possible distinct K pair and check if they are disjoint for every pair of all the ranges.

Time Complexity: O(N!)
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized by checking for every range the number of non-disjoint ranges which can be used with the current range. Follow the steps below to optimize the above approach:

• Initialize a variable, say, cnt to count the number of non-disjoint ranges for every current range.
• Initialize a vector of pairs, say preprocessed to store all the left boundary as {L[i], 1} and the right boundary as {R[i]+1, -1} of a range.
• Iterate over the range [0, N], using the variable i, and perform the following steps:
• Push the pairs {L[i], 1} and {R[i]+1, -1} into the vector preprocessed.
• Sort the vector, preprocessed in non-decreasing order.
• Initialize variables, say ans and cnt as 0 to store the answer and to store the segment that intersects with the current range.
• Iterate over the vector preprocessed using the variable i and do the following:
• If the second element of the pair is 1 and cnt >= K-1, then increase the ans by cntCK-1 and update cnt to cnt+1.
• Otherwise, update the cnt as cnt+1.
• Finally, after completing the above steps, print the ans.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Utility function to calculate nCr``int` `nCr(``int` `n, ``int` `r, ``int``* f)``{``    ``return` `f[n] / f[r] * f[n - r];``}` `// Function to calculate number of ways``// to choose K ranges such that no two of``// them are disjoint.``int` `NumberOfWaysToChooseKRanges(``int` `L[], ``int` `R[],``                                ``int` `N, ``int` `K)``{``    ``// Stores the factorials``    ``int` `f[N + 1];``    ``f = 1;` `    ``// Iterate over the range [1, N]``    ``for` `(``int` `i = 1; i <= N; i++) {``        ``f[i] = f[i - 1] * i;``    ``}` `    ``// Preprocessing the ranges into``    ``// new vector``    ``vector > preprocessed;` `    ``// Traverse the given ranges``    ``for` `(``int` `i = 0; i < N; i++) {``        ``preprocessed.push_back(make_pair(L[i], 1));``        ``preprocessed.push_back(make_pair(R[i] + 1, -1));``    ``}` `    ``// Sorting the preprocessed vector``    ``sort(preprocessed.begin(), preprocessed.end());` `    ``// Stores the result``    ``int` `ans = 0;` `    ``// Stores the count of non-disjoint ranges``    ``int` `Cnt = 0;` `    ``// Traverse the preprocessed vector of pairs``    ``for` `(``int` `i = 0; i < preprocessed.size(); i++) {` `        ``// If current point is a left boundary``        ``if` `(preprocessed[i].second == 1) {``            ``if` `(Cnt >= K - 1) {``                ``// Update the answer``                ``ans += nCr(Cnt, K - 1, f);``            ``}` `            ``// Increment cnt by 1``            ``Cnt++;``        ``}``        ``else` `{``            ``// Decrement cnt by 1``            ``Cnt--;``        ``}``    ``}` `    ``// Return the ans``    ``return` `ans;``}` `// Driver Code``int` `main()``{``    ``// Given Input``    ``int` `N = 7, K = 3;``    ``int` `L[] = { 1, 3, 4, 6, 1, 5, 8 };``    ``int` `R[] = { 7, 8, 5, 7, 3, 10, 9 };` `    ``// Function Call``    ``cout << NumberOfWaysToChooseKRanges(L, R, N, K);``    ``return` `0;``}`

## Java

 `// Java program for the above approach` `import` `java.io.*;``import` `java.util.*;` `class` `GFG {``  ` `static` `class` `pair``{``    ``int` `first, second;``     ` `    ``public` `pair(``int` `first, ``int` `second)``    ``{``        ``this``.first = first;``        ``this``.second = second;``    ``}  ``}`` ` `// Utility function to calculate nCr``static` `int` `nCr(``int` `n, ``int` `r, ``int` `f[])``{``    ``return` `f[n] / f[r] * f[n - r];``}` `// Function to calculate number of ways``// to choose K ranges such that no two of``// them are disjoint.``static` `int` `NumberOfWaysToChooseKRanges(``int` `L[], ``int` `R[],``                                ``int` `N, ``int` `K)``{``    ``// Stores the factorials``    ``int` `f[] = ``new` `int``[N + ``1``];``    ``f[``0``] = ``1``;` `    ``// Iterate over the range [1, N]``    ``for` `(``int` `i = ``1``; i <= N; i++) {``        ``f[i] = f[i - ``1``] * i;``    ``}` `    ``// Preprocessing the ranges into``    ``// new vector``    ``Vector preprocessed = ``new` `Vector();` `    ``// Traverse the given ranges``    ``for` `(``int` `i = ``0``; i < N; i++) {``        ``preprocessed.add(``new` `pair(L[i], ``1``));``        ``preprocessed.add(``new` `pair(R[i] + ``1``, -``1``));``    ``}` `    ``// Sorting the preprocessed vector``    ``Collections.sort(preprocessed, ``new` `Comparator() {``            ``@Override` `public` `int` `compare(pair p1, pair p2)``            ``{``                  ``if` `(p1.first != p2.first)``                    ``return` `(p1.first - p2.first);``                  ``return` `p1.second - p2.second;``            ``}``        ``});` `    ``// Stores the result``    ``int` `ans = ``0``;` `    ``// Stores the count of non-disjoint ranges``    ``int` `Cnt = ``0``;` `    ``// Traverse the preprocessed vector of pairs``    ``for` `(``int` `i = ``0``; i < preprocessed.size(); i++) {``        ` `        ``// If current point is a left boundary``        ``if` `(preprocessed.elementAt(i).second == ``1``) {``            ``if` `(Cnt >= K - ``1``) {``                ``// Update the answer``                ``ans += nCr(Cnt, K - ``1``, f);``            ``}` `            ``// Increment cnt by 1``            ``Cnt++;``        ``}``        ``else` `{``            ``// Decrement cnt by 1``            ``Cnt--;``        ``}``    ``}` `    ``// Return the ans``    ``return` `ans;``}` `// Driver Code``public` `static` `void` `main (String[] args) {``    ``// Given Input``    ``int` `N = ``7``, K = ``3``;``    ``int` `L[] = { ``1``, ``3``, ``4``, ``6``, ``1``, ``5``, ``8` `};``    ``int` `R[] = { ``7``, ``8``, ``5``, ``7``, ``3``, ``10``, ``9` `};` `    ``// Function Call``    ``System.out.println(NumberOfWaysToChooseKRanges(L, R, N, K));``}``}` `// This code is contributed by Dharanendra L V.`

## Python3

 `# Python3 program for the above approach` `# Utility function to calculate nCr``def` `nCr(n, r, f):``    ` `    ``return` `f[n] ``/``/` `f[r] ``*` `f[n ``-` `r]` `# Function to calculate number of ways``# to choose K ranges such that no two of``# them are disjoint.``def` `NumberOfWaysToChooseKRanges(L, R, N, K):``    ` `    ``# Stores the factorials``    ``f ``=` `[``0` `for` `i ``in` `range``(N ``+` `1``)]``    ``f[``0``] ``=` `1` `    ``# Iterate over the range [1, N]``    ``for` `i ``in` `range``(``1``, N ``+` `1``, ``1``):``        ``f[i] ``=` `f[i ``-` `1``] ``*` `i` `    ``# Preprocessing the ranges into``    ``# new vector``    ``preprocessed ``=` `[]` `    ``# Traverse the given ranges``    ``for` `i ``in` `range``(N):``        ``preprocessed.append([L[i], ``1``])``        ``preprocessed.append([R[i] ``+` `1``, ``-``1``])` `    ``# Sorting the preprocessed vector``    ``preprocessed.sort()` `    ``# Stores the result``    ``ans ``=` `0` `    ``# Stores the count of non-disjoint ranges``    ``Cnt ``=` `0` `    ``# Traverse the preprocessed vector of pairs``    ``for` `i ``in` `range``(``len``(preprocessed)):``        ` `        ``# If current point is a left boundary``        ``if` `(preprocessed[i][``1``] ``=``=` `1``):``            ``if` `(Cnt >``=` `K ``-` `1``):``                ` `                ``# Update the answer``                ``ans ``+``=` `nCr(Cnt, K ``-` `1``, f)` `            ``# Increment cnt by 1``            ``Cnt ``+``=` `1``        ``else``:``            ` `            ``# Decrement cnt by 1``            ``Cnt ``-``=` `1` `    ``# Return the ans``    ``return` `ans` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``# Given Input``    ``N ``=` `7``    ``K ``=` `3``    ``L ``=` `[ ``1``, ``3``, ``4``, ``6``, ``1``, ``5``, ``8` `]``    ``R ``=` `[ ``7``, ``8``, ``5``, ``7``, ``3``, ``10``, ``9` `]` `    ``# Function Call``    ``print``(NumberOfWaysToChooseKRanges(L, R, N, K))` `# This code is contributed by SURENDRA_GANGWAR`

## Javascript

 ``

Output

`9`

Time Complexity: O(N*log(N))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up