前提条件:BIT(二叉索引树或Fenwick树),2D BIT
给定2D平面,响应Q查询,以下每种类型:
- 插入xy –插入点(x,y)坐标。
- Triangle x1 y1 x2 y2 –通过连接矩形内的点(由两个点(x1,y1)和(x2,y2)来描述),打印可以形成的三角形数量,其中(x1,y1)在左下角而(x2,y2)是右上角。我们将其表示为{(x1,y1),(x2,y2)}。(在答案中也包括面积为零的三角形)
例子:
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.
假设我们以某种方式拥有一种机制,可以找到给定矩形内的点数,在实例中,点数为’m’。
可以形成的三角形数为m C 3 (连接时每3个点将组成一个三角形);如果只计算退化的三角形,则必须减去面积为零或由同一条线上的点组成的三角形的数量。
现在,我们潜入该机制以查找矩形中的点数。假设我们有一种机制可以找到矩形内的点数。
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)}
现在,一旦找到一种找到P(x,y)的方法,就完成了。
如果首先进行所有插入查询,然后进行所有三角查询,那将是一件容易的事,我们可以维护一个2D表来存储点,而table [x] [y]将包含点的总数。矩形{(1,1),(x,y)}。
可以使用以下DP创建它:
table [x] [y] = table [x] [y – 1] + table [x – 1] [y] – table [x – 1] [y – 1]
或者我们可以使用2D BIT插入点并评估P(x,y)。有关2D BIT的可视化,请参见Top Coder。该图显示了一个16 * 8 2D BIT,并且在(5,3)处插入后的状态是蓝色节点,该节点被更新一次。
水平BIT对应于3,将1存储在索引3中,将1存储在索引4中,将1存储在索引8中;垂直表示对应于哪个水平BIT将接收该更新,而垂直表示则对应于5,因此从底部开始的第5个BIT将得到一个更新,第6个BIT,然后是第8个BIT,然后是第16个BIT。
让我们考虑一维BIT中的更新
update(BIT, x)
while ( x < maxn )
BIT[x] += val
x += x & -x
2D BIT的更新如下:
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
#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;
}
Java
// Java program implementing the above queries
import java.util.*;
class GFG
{
static int maxn = 2005;
// 2D Binary Indexed Tree. Note: global variable
// will have initially all elements zero
static 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 rectangle
static 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 nC3
static int findTriangles(int n)
{
// returns pts choose 3
return (n * (n - 1) * (n - 2)) / 6;
}
// Driver Code
public 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 queries
maxn = 2005
# 2D Binary Indexed Tree.
# Note: global variable
# will have initially all
# elements zero
bit = [[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 rectangle
def 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
def findTriangles(n):
# returns pts choose 3
return ((n * (n - 1) *
(n - 2)) // 6)
# Driver code
if __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 queries
using System;
class GFG
{
static int maxn = 2005;
// 2D Binary Indexed Tree. Note: global variable
// will have initially all elements zero
static 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 rectangle
static 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 nC3
static int findTriangles(int n)
{
// returns pts choose 3
return (n * (n - 1) * (n - 2)) / 6;
}
// Driver Code
public 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
输出:
No of triangles in the rectangle (1, 1) (6, 6) are: 10
No of triangles in the rectangle (1, 1) (6, 6) are: 20