# Count number of intersections points for given lines between (i, 0) and (j, 1)

Given an array, lines[] of N pairs of the form (i, j) where (i, j) represents a line segment from coordinate (i, 0) to (j, 1), the task is to find the count of points of intersection of the given lines.

Example:

Input: lines[] = {{1, 2}, {2, 1}}
Output: 1
Explanation: For the given two pairs, the line form (1, 0) to (2, 1) intersect with the line from (2, 0) to (1, 1) at point (1.5, 0.5). Hence the total count of points of intersection is 1.

Input: lines[] = {{1, 5}, {2, 1}, {3, 7}, {4, 1}, {8, 2}}
Output: 5

Approach: The given problem can be solved using a Greedy approach using the policy-based data structure. It can be observed that for lines represented b two pairs (a, b) and (c, d) to intersect either (a > c and b < d) or (a < c and b > d) must hold true.

Therefore using this observation, the given array of pairs can be sorted in decreasing order of the 1st element. While traversing the array, insert the value of the second element into the policy-based data structure and find the count of elements smaller than the second element of the inserted pair using the order_of_key function and maintain the sum of count in a variable. Similarly, calculate for the cases after sorting the given array of pairs in decreasing order of their 2nd element.

Below is the implementation of the above approach:

## C++

 `// C++ Program of the above approach``#include ``#include ``using` `namespace` `__gnu_pbds;``using` `namespace` `std;` `// Defining Policy Based Data Structure``typedef` `tree<``int``, null_type,``             ``less_equal<``int``>, rb_tree_tag,``             ``tree_order_statistics_node_update>``    ``ordered_multiset;` `// Function to count points``// of intersection of pairs``// (a, b) and (c, d)``// such that a > c and b < d``int` `cntIntersections(``    ``vector > lines,``    ``int` `N)``{``    ``// Stores the count``    ``// of intersection points``    ``int` `cnt = 0;` `    ``// Initializing Ordered Multiset``    ``ordered_multiset s;` `    ``// Loop to iterate the array``    ``for` `(``int` `i = 0; i < N; i++) {` `        ``// Add the count of integers``        ``// smaller than lines[i].second``        ``// in the total count``        ``cnt += s.order_of_key(lines[i].second);` `        ``// Insert lines[i].second into s``        ``s.insert(lines[i].second);``    ``}` `    ``// Return Count``    ``return` `cnt;``}` `// Function to find the``// total count of points of``// intersections of all the given lines``int` `cntAllIntersections(``    ``vector > lines,``    ``int` `N)``{``    ``// Sort the array in decreasing``    ``// order of 1st element``    ``sort(lines.begin(), lines.end(),``         ``greater >());` `    ``// Stores the total count``    ``int` `totalCnt = 0;` `    ``// Function call for cases``    ``// with a > c and b < d``    ``totalCnt += cntIntersections(lines, N);` `    ``// Swap all the pairs of the array in order``    ``// to calculate cases with a < c and b > d``    ``for` `(``int` `i = 0; i < N; i++) {``        ``swap(lines[i].first, lines[i].second);``    ``}` `    ``// Function call for cases``    ``// with a < c and b > d``    ``totalCnt += cntIntersections(lines, N);` `    ``// Return Answer``    ``return` `totalCnt;``}` `// Driver Code``int` `main()``{``    ``vector > lines{``        ``{1, 5}, {2, 1}, {3, 7}, {4, 1}, {8, 2}``    ``};` `    ``cout << cntAllIntersections(lines,``                                ``lines.size());` `    ``return` `0;``}`

## Java

 `import` `java.io.*;``import` `java.lang.*;``import` `java.util.*;``// Importing the policy-based data structure``import` `java.util.TreeSet;``import` `java.util.function.*;` `class` `Main {``    ``// Function to count points``    ``// of intersection of pairs``    ``// (a, b) and (c, d)``    ``// such that a > c and b < d``    ``static` `int` `cntIntersections(Pair[] lines, ``int` `N)``    ``{``        ``// Stores the count``        ``// of intersection points``        ``int` `cnt = ``0``;` `        ``// Initializing TreeSet``        ``TreeSet s = ``new` `TreeSet();` `        ``// Loop to iterate the array``        ``for` `(``int` `i = ``0``; i < N; i++) {` `            ``// Add the count of integers``            ``// smaller than lines[i].second``            ``// in the total count``            ``cnt += s.headSet(lines[i].b, ``true``).size();` `            ``// Insert lines[i].second into s``            ``s.add(lines[i].b);``        ``}` `        ``// Return Count``        ``return` `cnt;``    ``}` `    ``// Function to find the``    ``// total count of points of``    ``// intersections of all the given lines``    ``static` `int` `cntAllIntersections(Pair[] lines, ``int` `N)``    ``{``        ``// Sort the array in decreasing``        ``// order of 1st element``        ``Arrays.sort(lines, ``new` `Comparator() {``            ``public` `int` `compare(Pair p1, Pair p2)``            ``{``                ``if` `(p1.a == p2.a) {``                    ``return` `p1.b - p2.b;``                ``}``                ``return` `p2.a - p1.a;``            ``}``        ``});` `        ``// Stores the total count``        ``int` `totalCnt = ``0``;` `        ``// Function call for cases``        ``// with a > c and b < d``        ``totalCnt += cntIntersections(lines, N);` `        ``// Swap all the pairs of the array in order``        ``// to calculate cases with a < c and b > d``        ``for` `(``int` `i = ``0``; i < N; i++) {``            ``int` `temp = lines[i].a;``            ``lines[i].a = lines[i].b;``            ``lines[i].b = temp;``        ``}` `        ``// Function call for cases``        ``// with a < c and b > d``        ``totalCnt += cntIntersections(lines, N);` `        ``// Return Answer``        ``return` `totalCnt;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``Pair[] lines = { ``new` `Pair(``1``, ``5``), ``new` `Pair(``2``, ``1``),``                         ``new` `Pair(``3``, ``7``), ``new` `Pair(``4``, ``1``),``                         ``new` `Pair(``8``, ``2``) };` `        ``System.out.println(``            ``cntAllIntersections(lines, lines.length));``    ``}` `    ``// Pair class to represent a pair of integers``    ``static` `class` `Pair {``        ``int` `a, b;` `        ``Pair(``int` `a, ``int` `b)``        ``{``            ``this``.a = a;``            ``this``.b = b;``        ``}``    ``}``}`

## Python3

 `# Python3 implementation of the above approach` `# Importing in-built module for sorting and bisect_left method``from` `bisect ``import` `*` `# Defining function to count points of intersection of pairs``def` `cntIntersections(lines, N):``    ``# Stores the count of intersection points``    ``cnt ``=` `0` `    ``# Initializing list to store ending points of lines``    ``s ``=` `[]` `    ``# Loop to iterate the array``    ``for` `i ``in` `range``(N):``        ``# Add the count of integers smaller than lines[i][1] in the total count``        ``cnt ``+``=` `bisect_left(s, lines[i][``1``])``        ``# Insert lines[i][1] into s``        ``s.append(lines[i][``1``])``        ``s.sort()``        ` `    ``# Return Count``    ``return` `cnt` `# Function to find the total count of points of intersections of all the given lines``def` `cntAllIntersections(lines, N):``    ``# Sort the array in decreasing order of 1st element``    ``lines ``=` `sorted``(lines, reverse``=``True``)` `    ``# Stores the total count``    ``totalCnt ``=` `0` `    ``# Function call for cases with a > c and b < d``    ``totalCnt ``+``=` `cntIntersections(lines, N)` `    ``# Swap all the pairs of the array in order to calculate cases with a < c and b > d``    ``lines ``=` `[(b, a) ``for` `(a, b) ``in` `lines]` `    ``# Function call for cases with a < c and b > d``    ``totalCnt ``+``=` `cntIntersections(lines, N)` `    ``# Return Answer``    ``return` `totalCnt` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``lines ``=` `[(``1``, ``5``), (``2``, ``1``), (``3``, ``7``), (``4``, ``1``), (``8``, ``2``)]``    ``print``(cntAllIntersections(lines, ``len``(lines)))`

## C#

 `using` `System;``using` `System.Collections.Generic;` `public` `class` `Program {``    ``// Function to count points``    ``// of intersection of pairs``    ``// (a, b) and (c, d)``    ``// such that a > c and b < d``    ``static` `int` `cntIntersections(Pair[] lines, ``int` `N)``    ``{``        ``// Stores the count``        ``// of intersection points``        ``int` `cnt = 0;``        ``// Initializing SortedSet``        ``SortedSet<``int``> s = ``new` `SortedSet<``int``>();` `        ``// Loop to iterate the array``        ``for` `(``int` `i = 0; i < N; i++) {``            ``// Add the count of integers``            ``// smaller than lines[i].second``            ``// in the total count``            ``cnt += s.GetViewBetween(``int``.MinValue,``                                    ``lines[i].b)``                       ``.Count;` `            ``// Insert lines[i].second into s``            ``s.Add(lines[i].b);``        ``}` `        ``// Return Count``        ``return` `cnt;``    ``}` `    ``// Function to find the``    ``// total count of points of``    ``// intersections of all the given lines``    ``static` `int` `cntAllIntersections(Pair[] lines, ``int` `N)``    ``{``        ``// Sort the array in decreasing``        ``// order of 1st element``        ``Array.Sort(lines, ``new` `PairComparer());` `        ``// Stores the total count``        ``int` `totalCnt = 0;` `        ``// Function call for cases``        ``// with a > c and b < d``        ``totalCnt += cntIntersections(lines, N);` `        ``// Swap all the pairs of the array in order``        ``// to calculate cases with a < c and b > d``        ``for` `(``int` `i = 0; i < N; i++) {``            ``int` `temp = lines[i].a;``            ``lines[i].a = lines[i].b;``            ``lines[i].b = temp;``        ``}` `        ``// Function call for cases``        ``// with a < c and b > d``        ``totalCnt += cntIntersections(lines, N);` `        ``// Return Answer``        ``return` `totalCnt;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main()``    ``{``        ``Pair[] lines = { ``new` `Pair(1, 5), ``new` `Pair(2, 1),``                         ``new` `Pair(3, 7), ``new` `Pair(4, 1),``                         ``new` `Pair(8, 2) };` `        ``Console.WriteLine(``            ``cntAllIntersections(lines, lines.Length));``    ``}` `    ``// Pair class to represent a pair of integers``    ``public` `class` `Pair {``        ``public` `int` `a, b;` `        ``public` `Pair(``int` `a, ``int` `b)``        ``{``            ``this``.a = a;``            ``this``.b = b;``        ``}``    ``}` `    ``// PairComparer class to compare pairs in decreasing``    ``// order``    ``public` `class` `PairComparer : IComparer {``        ``public` `int` `Compare(Pair p1, Pair p2)``        ``{``            ``if` `(p1.a == p2.a) {``                ``return` `p1.b - p2.b;``            ``}``            ``return` `p2.a - p1.a;``        ``}``    ``}``}`

## Javascript

 `// Defining function to count points of intersection of pairs``function` `cntIntersections(lines, N) {``    ``// Stores the count of intersection points``    ``let cnt = 0;` `    ``// Initializing list to store ending points of lines``    ``let s = [];` `    ``// Loop to iterate the array``    ``for` `(let i = 0; i < N; i++) {``        ``// Add the count of integers smaller than lines[i][1] in the total count``        ``cnt += s.filter(x => x < lines[i][1]).length;``        ``// Insert lines[i][1] into s``        ``s.push(lines[i][1]);``        ``s.sort((a, b) => a - b);``    ``}` `    ``// Return Count``    ``return` `cnt;``}` `// Function to find the total count of points of intersections of all the given lines``function` `cntAllIntersections(lines, N) {``    ``// Sort the array in decreasing order of 1st element``    ``lines = lines.sort((a, b) => b[0] - a[0]);` `    ``// Stores the total count``    ``let totalCnt = 0;` `    ``// Function call for cases with a > c and b < d``    ``totalCnt += cntIntersections(lines, N);` `    ``// Swap all the pairs of the array in order to calculate cases with a < c and b > d``    ``lines = lines.map(x => [x[1], x[0]]);` `    ``// Function call for cases with a < c and b > d``    ``totalCnt += cntIntersections(lines, N);` `    ``// Return Answer``    ``return` `totalCnt;``}` `// Driver Code``let lines = [[1, 5], [2, 1], [3, 7], [4, 1], [8, 2]];``console.log(cntAllIntersections(lines, lines.length));`

Output:
`5`

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

Previous
Next