# Counting Triangles in a Rectangular space using BIT

Pre-requisite : BIT(Binary Indexed Tree or Fenwick Tree), 2D BIT

Given a 2D plane, respond to Q queries, each of the following type:

**Insert x y**– Insert a point (x, y) coordinate.**Triangle x1 y1 x2 y2**– Print the number of triangles that can be formed, by joining the points inside the rectangle, described by two points (x1, y1) and (x2, y2), (x1, y1) is the lower left corner while (x2, y2) is the upper right corner. We will represent it as {(x1, y1), (x2, y2)}.(Include the the triangles with zero area also in your answer)

Example:

In the red rectangle there are 6 points inserted, when each of them is joined with a line with every other point, in all 20 triangles will be formed.

Let’s say we somehow have a mechanism to find the number of points inside a given rectangle, let number of points be ‘m’ in an instance.

Number of triangles that can be formed with it are ** ^{m}C_{3}** (every 3 points when joined will make a triangle); if we had to count only degenerate triangles, we would have to subtract the number of triangles with zero area or formed from points on the same line.

Now we sneak into the mechanism to find the number of points in a rectangle; let’s assume we have a mechanism to find number of points inside a rectangle .

Then number of points inside the rectangle {(x1, y1), (x2, y2)} are,P(x2, y2) - P(x1 - 1, y2) - P(x2, y1 - 1) + P(x1 - 1, y1 - 1)Where, P(x, y) is number of triangles in rectangle from (1, 1) to (x, y), i.e., {(1, 1), (x, y)}

Now once we find a way to find P(x, y), we are done.

If all the insert queries were made first, then all the triangle queries, it would have been an easy job, we could maintain a 2D table to store the points and table[x][y] would contain the total number of points in the rectangle {(1, 1), (x, y)}.

It can be created using the following DP:

**table[x][y] = table[x][y – 1] + table[x – 1][y] – table[x – 1][y – 1]**

Or we can use a 2D BIT to insert a point and evaluate P(x, y). For visualization of a 2D BIT, refer Top Coder.The image shows a 16 * 8 2D BIT, and the state after an insertion at (5, 3), the blue nodes are the onces that are updated.

The horizontal BITs correspond to 3, and store 1 at index 3, 1 at index 4, and 1 at index 8; while the vertical representation corresponds to which horizontal BITs will recieve that update, the ones that correspond to 5, so 5th BIT from bottom gets an update, 6th BIT, then 8th BIT, and then 16th BIT.

Let’s consider update in a 1D BIT

update(BIT, x) while ( x < maxn ) BIT[x] += val x += x & -x

Update for 2D BIT goes like:

update2DBIT(x, y) // update BIT at index x (from bottom, in the image) while ( x < maxn ) update(BIT[x], y) x += x & -x

`// A C++ program implementing the above queries ` `#include<bits/stdc++.h> ` `#define maxn 2005 ` `using` `namespace` `std; ` ` ` `// 2D Binary Indexed Tree. Note: global variable ` `// will have initially all elements zero ` `int` `bit[maxn][maxn]; ` ` ` `// function to add a point at (x, y) ` `void` `update(` `int` `x, ` `int` `y) ` `{ ` ` ` `int` `y1; ` ` ` `while` `(x < maxn) ` ` ` `{ ` ` ` `// x is the xth BIT that will be updated ` ` ` `// while y is the indices where an update ` ` ` `// will be made in xth BIT ` ` ` `y1 = y; ` ` ` `while` `( y1 < maxn ) ` ` ` `{ ` ` ` `bit[x][y1]++; ` ` ` `y1 += ( y1 & -y1 ); ` ` ` `} ` ` ` ` ` `// next BIT that should be updated ` ` ` `x += x & -x; ` ` ` `} ` `} ` ` ` `// Function to return number of points in the ` `// rectangle (1, 1), (x, y) ` `int` `query(` `int` `x, ` `int` `y) ` `{ ` ` ` `int` `res = 0, y1; ` ` ` `while` `(x > 0) ` ` ` `{ ` ` ` `// xth BIT's yth node must be added to the result ` ` ` `y1 = y; ` ` ` `while` `(y1 > 0) ` ` ` `{ ` ` ` `res += bit[x][y1]; ` ` ` `y1 -= y1 & -y1; ` ` ` `} ` ` ` ` ` `// next BIT that will contribute to the result ` ` ` `x -= x & -x; ` ` ` `} ` ` ` `return` `res; ` `} ` ` ` `// (x1, y1) is the lower left and (x2, y2) is the ` `// upper right corner of the rectangle ` `int` `pointsInRectangle(` `int` `x1, ` `int` `y1, ` `int` `x2, ` `int` `y2) ` `{ ` ` ` `// Returns number of points in the rectangle ` ` ` `// (x1, y1), (x2, y2) as described in text above ` ` ` `return` `query(x2, y2) - query(x1 - 1, y2) -W ` ` ` `query(x2, y1 - 1) + query(x1 - 1, y1 - 1); ` `} ` ` ` `// Returns count of triangles with n points, i.e., ` `// it returns nC3 ` `int` `findTriangles(` `int` `n) ` `{ ` ` ` `// returns pts choose 3 ` ` ` `return` `(n * (n - 1) * (n - 2)) / 6; ` `} ` ` ` `//driver code ` `int` `main() ` `{ ` ` ` `//inserting points ` ` ` `update(2, 2); ` ` ` `update(3, 5); ` ` ` `update(4, 2); ` ` ` `update(4, 5); ` ` ` `update(5, 4); ` ` ` ` ` `cout << ` `"No. of triangles in the rectangle (1, 1)"` ` ` `" (6, 6) are: "` ` ` `<< findTriangles(pointsInRectangle(1, 1, 6, 6)); ` ` ` ` ` `update(3, 3); ` ` ` ` ` `cout << ` `"\nNo. of triangles in the rectangle (1, 1)"` ` ` `" (6, 6) are: "` ` ` `<< findTriangles( pointsInRectangle(1, 1, 6, 6)); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

Output:

No of triangles in the rectangle (1, 1) (6, 6) are: 10 No of triangles in the rectangle (1, 1) (6, 6) are: 20

**Time Complexity : ** For each query of either type: ** O(log(x) * log(y))** Or infact: **O( number of ones in binary representation of x * number of ones in binary representation of y )**

Total time complexity: **O(Q * log(maxX) * log(maxY))**

This article is contributed by **Saumye Malhotra ** .If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

## Recommended Posts:

- Largest Rectangular Area in a Histogram | Set 1
- Count the number of possible triangles
- Number of triangles after N moves
- Find all possible triangles with XOR of sides zero
- Counting the number of words in a Trie
- Counting k-mers via Suffix Array
- Area of the circumcircle of any triangles with sides given
- Program to check similarity of given two triangles
- Program to check congruency of two triangles
- Count number of unique Triangles using STL | Set 1 (Using set)
- Number of triangles that can be formed with given N points
- Number of Triangles in an Undirected Graph
- Counting inversions in an array using segment tree
- Number of triangles possible with given lengths of sticks which are powers of 2
- Number of possible Triangles in a Cartesian coordinate system