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

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: 2
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: 0
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 .
• We pre-calculate the inverse and factorial of required numbers to calculate 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 where p = size_of_multiset.
• Insert end-point of this line-segment in the multiset.

Below is the implementation of the above approach:

 `// 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; ` `} `

Output:

```2
``` My Personal Notes arrow_drop_up