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 triangles with zero areas 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 the number of points be ‘m’ in an instance.
The number of triangles that can be formed with it are mC3 (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 areas 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 the 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 receive that update, the ones that correspond to 5, so 5th BIT from the 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
C++
// A C++ program implementing the above queries#include<bits/stdc++.h>#define maxn 2005using namespace std;// 2D Binary Indexed Tree. Note: global variable// will have initially all elements zeroint 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 rectangleint 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) - query(x2, y1 - 1) + query(x1 - 1, y1 - 1);}// Returns count of triangles with n points, i.e.,// it returns nC3int findTriangles(int n){ // returns pts choose 3 return (n * (n - 1) * (n - 2)) / 6;}//driver codeint 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;} |
Java
// Java program implementing the above queriesimport java.util.*;class GFG{static int maxn = 2005;// 2D Binary Indexed Tree. Note: global variable// will have initially all elements zerostatic int [][]bit = new int[maxn][maxn];// function to add a point at (x, y)static 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)static 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 rectanglestatic 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) - query(x2, y1 - 1) + query(x1 - 1, y1 - 1);}// Returns count of triangles with n points, i.e.,// it returns nC3static int findTriangles(int n){ // returns pts choose 3 return (n * (n - 1) * (n - 2)) / 6;}// Driver Codepublic static void main(String[] args){ // inserting points update(2, 2); update(3, 5); update(4, 2); update(4, 5); update(5, 4); System.out.print("No. of triangles in the " + "rectangle (1, 1) (6, 6) are: " + findTriangles(pointsInRectangle(1, 1, 6, 6))); update(3, 3); System.out.print("\nNo. of triangles in the " + "rectangle (1, 1) (6, 6) are: " + findTriangles( pointsInRectangle(1, 1, 6, 6)));}}// This code is contributed by Rajput-Ji |
Python3
# A Python3 program implementing# the above queriesmaxn = 2005# 2D Binary Indexed Tree.# Note: global variable# will have initially all # elements zerobit = [[0 for j in range(maxn)] for i in range(maxn)]# function to add a point # at(x, y)def update(x, y): y1 = 0 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] += 1 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)def query(x, y): res = 0 y1 = 0 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 rectangledef pointsInRectangle(x1, y1, x2, 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) - query(x2, y1 - 1) + query(x1 - 1, y1 - 1))# Returns count of triangles with # n points, i.e., it returns nC3def findTriangles(n): # returns pts choose 3 return ((n * (n - 1) * (n - 2)) // 6)# Driver codeif __name__ == "__main__": # inserting points update(2, 2) update(3, 5) update(4, 2) update(4, 5) update(5, 4) print("No. of triangles in the " + "rectangle (1, 1) (6, 6) are: ", findTriangles(pointsInRectangle(1, 1, 6, 6))) update(3, 3) print("No. of triangles in the rectangle " + "(1, 1) (6, 6) are:", findTriangles( pointsInRectangle(1, 1, 6, 6)))# This code is contributed by Rutvik_56 |
C#
// C# program implementing the above queriesusing System;class GFG{static int maxn = 2005;// 2D Binary Indexed Tree. Note: global variable// will have initially all elements zerostatic int [,]bit = new int[maxn, maxn];// function to add a point at (x, y)static 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)static 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 rectanglestatic 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) - query(x2, y1 - 1) + query(x1 - 1, y1 - 1);}// Returns count of triangles with n points, i.e.,// it returns nC3static int findTriangles(int n){ // returns pts choose 3 return (n * (n - 1) * (n - 2)) / 6;}// Driver Codepublic static void Main(String[] args){ // inserting points update(2, 2); update(3, 5); update(4, 2); update(4, 5); update(5, 4); Console.Write("No. of triangles in the " + "rectangle (1, 1) (6, 6) are: " + findTriangles(pointsInRectangle(1, 1, 6, 6))); update(3, 3); Console.Write("\nNo. of triangles in the " + "rectangle (1, 1) (6, 6) are: " + findTriangles( pointsInRectangle(1, 1, 6, 6)));}}// This code is contributed by PrinciRaj1992 |
Javascript
<script>// JavaScript program implementing the above queries var maxn = 2005; // 2D Binary Indexed Tree. Note: global variable // will have initially all elements zero var bit = Array(maxn).fill().map(()=>Array(maxn).fill(0)); // function to add a point at (x, y) function update(x , y) { var 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) function query(x , y) { var 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 function pointsInRectangle(x1 , y1 , x2 , 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) - query(x2, y1 - 1) + query(x1 - 1, y1 - 1); } // Returns count of triangles with n points, i.e., // it returns nC3 function findTriangles(n) { // returns pts choose 3 return (n * (n - 1) * (n - 2)) / 6; } // Driver Code // inserting points update(2, 2); update(3, 5); update(4, 2); update(4, 5); update(5, 4); document.write("No. of triangles in the " + "rectangle (1, 1) (6, 6) are: " + findTriangles(pointsInRectangle(1, 1, 6, 6))); update(3, 3); document.write("<br/>No. of triangles in the " + "rectangle (1, 1) (6, 6) are: " + findTriangles(pointsInRectangle(1, 1, 6, 6)));// This code contributed by gauravrajput1</script> |
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 a binary representation of y )
Total time complexity: O(Q * log(maxX) * log(maxY))
This article is contributed by Saumye Malhotra .If you like neveropen and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the neveropen 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.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!


… [Trackback]
[…] Find More on that Topic: geeksforgeeks.org/counting-triangles-in-a-rectangular-space-using-bit/ […]
… [Trackback]
[…] There you will find 33660 more Information on that Topic: geeksforgeeks.org/counting-triangles-in-a-rectangular-space-using-bit/ […]
… [Trackback]
[…] Read More here on that Topic: geeksforgeeks.org/counting-triangles-in-a-rectangular-space-using-bit/ […]