Related Articles

# Number of ways to choose K intersecting line segments on X-axis

• Last Updated : 18 Nov, 2020

Given an array arr[] of line segments on the x-axis and an integer K, the task is to calculate the number of ways to choose the K line-segments such that they do intersect at any point. Since the answer can be large, print it to modulo 10^9+7.

Examples:

Input: arr[] = [[1, 3], [4, 5], [5, 7]], K = 2
Output:
Explanation:
The first way to choose [1, 3], [4, 5] and the second way is [1, 3], [5, 7].Since Intersection of [4, 5], [5, 7] is not zero and hence cannot be included in answer.

Input: [[3, 7], [1, 4], [6, 9], [8, 13], [9, 11]], K = 1
Output:
Explanation:
Since we are only looking for single line segment, but for every single line segment Intersection is always non empty.

Approach:
To solve the problem mentioned above we will try to find out the number of odd cases means those cases whose intersection is non-empty. So clearly our answer will be Total Case – Odd Case.
To compute the total number of cases, the below approach is followed:

• Total cases that are possible are “n choose k” or nCk
• We pre-calculate the inverse and factorial of required numbers to calculate nCk
• in O(1) time
• The K line-segment intersect as if min(R1, R2, .., R{k-1}) >= Li where line-segment [Li, Ri] is under consideration. Maintain a multiset, to maintain order. Firstly, sort the segments in increasing order of Li . If Li are same then the segment with smaller Ri comes first.

For every line-segment [Li, Ri], the approach below is followed to find the number of odd cases.

• While multiset is not empty, and the lines don’t intersect then delete the line with smallest Ri from multiset and check again.
• Number of violating ways using this segment [Li, Ri] are pCk-1
• where p = size_of_multiset.
• Insert end-point of this line-segment in the multiset.

Below is the implementation of the above approach:

## C++

 `// C++ program to find Number of ways``// to choose K intersecting``// line segments on X-axis` `#include ``using` `namespace` `std;` `const` `long` `long` `mod = 1000000007;``const` `int` `MAXN = 1001;``long` `long` `factorial[MAXN], inverse[MAXN];` `// Function to find (a^b)%mod in log b``long` `long` `power(``long` `long` `a, ``long` `long` `b)``{``    ``long` `long` `res = 1;` `    ``// Till power becomes 0``    ``while` `(b > 0) {` `        ``// If power is odd``        ``if` `(b % 2 == 1) {``            ``res = (res * a) % mod;``        ``}``        ``// Multiply base``        ``a = (a * a) % mod;` `        ``// Divide power by 1``        ``b >>= 1;``    ``}` `    ``return` `res;``}` `// Function to find nCk``long` `long` `nCk(``int` `n, ``int` `k)``{``    ``// Base case``    ``if` `(k < 0 || k > n) {``        ``return` `0;``    ``}` `    ``// Apply formula to find nCk``    ``long` `long` `ans = factorial[n];``    ``ans = (ans * inverse[n - k]) % mod;``    ``ans = (ans * inverse[k]) % mod;` `    ``return` `ans;``}` `// Function to find the number of ways``void` `numberOfWays(vector > lines, ``int` `K,``                  ``int` `N)``{` `    ``// sort the given lines``    ``sort(lines.begin(), lines.end());` `    ``// Find the number of total case``    ``long` `long` `total_case = nCk(N, K);` `    ``// Declare a multiset``    ``multiset<``int``> m;` `    ``// loop till N``    ``for` `(``int` `i = 0; i < N; i++)``    ``{` `        ``// Check if smallest element is``        ``// smaller than lines[i]``        ``while` `(!m.empty()``               ``&& (*m.begin() < lines[i].first)) {` `            ``// Erase first element``            ``m.erase(m.begin());``        ``}``        ``// Exclude the odd cases``        ``total_case -= nCk(m.size(), K - 1);` `        ``// Modulus operation``        ``total_case += mod;``        ``total_case %= mod;` `        ``// Insert into multiset``        ``m.insert(lines[i].second);``    ``}` `    ``cout << total_case << endl;``}` `// Function to precompute``// factorial and inverse``void` `preCompute()``{``    ``long` `long` `fact = 1;` `    ``factorial = 1;``    ``inverse = 1;` `    ``// Pre-compute factorial and inverse``    ``for` `(``int` `i = 1; i < MAXN; i++) {` `        ``fact = (fact * i) % mod;``        ``factorial[i] = fact;``        ``inverse[i] = power(factorial[i], mod - 2);``    ``}``}` `// Driver code``int` `main()``{` `    ``int` `N = 3, K = 2;``    ``vector > lines;` `    ``// Function to pre-compute``    ``// factorial and inverse``    ``preCompute();` `    ``lines.push_back({ 1, 3 });``    ``lines.push_back({ 4, 5 });``    ``lines.push_back({ 5, 7 });` `    ``numberOfWays(lines, K, N);` `    ``return` `0;``}`

## Java

 `// Java program to find Number of ways``// to choose K intersecting line``// segments on X-axis``import` `java.util.*;``import` `java.lang.*;` `class` `GFG {` `    ``static` `long` `mod = ``1000000007``;``    ``static` `int` `MAXN = ``1001``;``    ``static` `long` `factorial[] = ``new` `long``[MAXN],``                ``inverse[] = ``new` `long``[MAXN];` `    ``// Function to find (a^b)%mod in log b``    ``static` `long` `power(``long` `a, ``long` `b)``    ``{``        ``long` `res = ``1``;` `        ``// Till power becomes 0``        ``while` `(b > ``0``) {` `            ``// If power is odd``            ``if` `(b % ``2` `== ``1``) {``                ``res = (res * a) % mod;``            ``}` `            ``// Multiply base``            ``a = (a * a) % mod;` `            ``// Divide power by 1``            ``b >>= ``1``;``        ``}``        ``return` `res;``    ``}` `    ``// Function to find nCk``    ``static` `long` `nCk(``int` `n, ``int` `k)``    ``{` `        ``// Base case``        ``if` `(k < ``0` `|| k > n) {``            ``return` `0``;``        ``}` `        ``// Apply formula to find nCk``        ``long` `ans = factorial[n];``        ``ans = (ans * inverse[n - k]) % mod;``        ``ans = (ans * inverse[k]) % mod;` `        ``return` `ans;``    ``}` `    ``// Function to find the number of ways``    ``static` `void` `numberOfWays(ArrayList<``int``[]> lines, ``int` `K,``                             ``int` `N)``    ``{` `        ``// sort the given lines``        ``Collections.sort(lines, (a, b) -> a[``0``] - b[``0``]);` `        ``// Find the number of total case``        ``long` `total_case = nCk(N, K);` `        ``// Declare a multiset``        ``PriorityQueue m = ``new` `PriorityQueue<>();` `        ``// Loop till N``        ``for` `(``int` `i = ``0``; i < N; i++) {` `            ``// Check if smallest element is``            ``// smaller than lines[i]``            ``while` `(!m.isEmpty()``                   ``&& (m.peek() < lines.get(i)[``0``])) {` `                ``// Erase first element``                ``m.poll();``            ``}` `            ``// Exclude the odd cases``            ``total_case -= nCk(m.size(), K - ``1``);` `            ``// Modulus operation``            ``total_case += mod;``            ``total_case %= mod;` `            ``// Insert into multiset``            ``m.add(lines.get(i)[``1``]);``        ``}``        ``System.out.println(total_case);``    ``}` `    ``// Function to precompute``    ``// factorial and inverse``    ``static` `void` `preCompute()``    ``{``        ``long` `fact = ``1``;` `        ``factorial[``0``] = ``1``;``        ``inverse[``0``] = ``1``;` `        ``// Pre-compute factorial and inverse``        ``for` `(``int` `i = ``1``; i < MAXN; i++) {``            ``fact = (fact * i) % mod;``            ``factorial[i] = fact;` `            ``inverse[i] = power(factorial[i], mod - ``2``);``        ``}``    ``}` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `N = ``3``, K = ``2``;``        ``ArrayList<``int``[]> lines = ``new` `ArrayList<>();` `        ``// Function to pre-compute``        ``// factorial and inverse``        ``preCompute();` `        ``lines.add(``new` `int``[] { ``1``, ``3` `});``        ``lines.add(``new` `int``[] { ``4``, ``5` `});``        ``lines.add(``new` `int``[] { ``5``, ``7` `});` `        ``numberOfWays(lines, K, N);``    ``}``}` `// This code is contributed by offbeat`
Output
```2

```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up