Data Structure: Line Segment tree

Source: Internet
Author: User

I. Basic concepts of line tree
A line segment tree is a binary search tree similar to an interval tree. It divides an interval into several unit intervals. Each unit interval corresponds to a leaf node in a line segment tree.
For each non-leaf node [a, B] In a line segment tree, its left son represents the interval [a, (a + B)/2], the range indicated by the right son is [(a + B)/2 + 1, B]. Therefore, a line segment tree is a balanced binary tree. The number of subnodes is N, that is, the length of the entire line segment.

You can use the line segment tree to quickly find the number of times a node appears in several line segments. The time complexity is O (logN ). The unoptimized space complexity is 2N. Therefore, it is sometimes necessary to compress the space by discretization.

Nature: the father's range is [a, B], (c = (a + B)/2) the left son's range is [a, c], the range of the right son is [c + 1, B]. The space required by the line segment tree is four times the size of the array.

 

2. Storage Data Structure of the Line Segment tree
From the figure above, we can see that the storage of a line segment tree is a bit similar to that of a binary tree. The left and right child nodes are required. In addition, to store the number of times each line segment appears, therefore, the counting element is usually added as follows:

[Cpp]
Struct Node // line segment tree
{
Int left;
Int right;
Int counter;
} SegTree [4 * BORDER];

Struct Node // line segment tree
{
Int left;
Int right;
Int counter;
} SegTree [4 * BORDER];
Left indicates the left endpoint, right indicates the right endpoint, counter indicates the number of occurrences of each line segment, and BORDE indicates that the coordinate of the Line Segment endpoint cannot exceed 100. We can see from the above nature that we need 4 times of space for storage.

3. operations supported by the line segment tree
A line segment tree supports at least four operations:

Void construct (int index, int lef, int rig) to build the line segment tree. The root node of the Line Segment tree starts to build the line segment tree with the interval [lef, rig ].
Void insert (int index, int start, int end), insert a line segment [start, end] to the line segment tree, count the number of times at the same time
Int query (int index, int x): The number of times x appears in the query point. From the root node to the number of times x appears in the path of the [x, x] leaf.
Void delete _ (int c, int d, int index), delete a line segment from the line segment tree [c, d]

The procedure is as follows:

1. Create a line segment tree


[Cpp]
/* Construct the root node of the Line Segment tree and start to build the line segment tree in the interval [lef, rig */
Void construct (int index, int lef, int rig)
{
SegTree [index]. left = lef;
SegTree [index]. right = rig;
If (lef = rig) // leaf node
{
SegTree [index]. counter = 0;
Return;
}
Int mid = (lef + rig)> 1;
Construct (index <1) + 1, lef, mid );
Construct (index <1) + 2, mid + 1, rig );
SegTree [index]. counter = 0;
}

/* Construct the root node of the Line Segment tree and start to build the line segment tree in the interval [lef, rig */
Void construct (int index, int lef, int rig)
{
SegTree [index]. left = lef;
SegTree [index]. right = rig;
If (lef = rig) // leaf node
{
SegTree [index]. counter = 0;
Return;
}
Int mid = (lef + rig)> 1;
Construct (index <1) + 1, lef, mid );
Construct (index <1) + 2, mid + 1, rig );
SegTree [index]. counter = 0;
}

2. Insert elements of a line segment tree

[Cpp]
/* Insert a line segment [start, end] to the line segment tree and count the number of times */
Void insert (int index, int start, int end)
{
If (segTree [index]. left = start & segTree [index]. right = end)
{
++ SegTree [index]. counter;
Return;
}
Int mid = (segTree [index]. left + segTree [index]. right)> 1;
If (end <= mid) // left subtree
{
Insert (index <1) + 1, start, end );
} Else if (start> mid) // right subtree
{
Insert (index <1) + 2, start, end );
} Else // split
{
Insert (index <1) + 1, start, mid );
Insert (index <1) + 2, mid + 1, end );
}
}

/* Insert a line segment [start, end] to the line segment tree and count the number of times */
Void insert (int index, int start, int end)
{
If (segTree [index]. left = start & segTree [index]. right = end)
{
++ SegTree [index]. counter;
Return;
}
Int mid = (segTree [index]. left + segTree [index]. right)> 1;
If (end <= mid) // left subtree
{
Insert (index <1) + 1, start, end );
} Else if (start> mid) // right subtree
{
Insert (index <1) + 2, start, end );
} Else // split
{
Insert (index <1) + 1, start, mid );
Insert (index <1) + 2, mid + 1, end );
}
}
3. Search for line segment Tree Elements

[Cpp]
/* Number of times point x appears
* From the root node to the path of the [x, x] leaf, the number of times x appears when the sum of some counts is x.
*/
Int query (int index, int x)
{
If (segTree [index]. left = segTree [index]. right) // go to the leaf and return
{
Return segTree [index]. counter;
}
Int mid = (segTree [index]. left + segTree [index]. right)> 1;
If (x <= mid)
{
Return segTree [index]. counter + query (index <1) + 1, x );
}
Return segTree [index]. counter + query (index <1) + 2, x );
}

/* Number of times point x appears
* From the root node to the path of the [x, x] leaf, the number of times x appears when the sum of some counts is x.
*/
Int query (int index, int x)
{
If (segTree [index]. left = segTree [index]. right) // go to the leaf and return
{
Return segTree [index]. counter;
}
Int mid = (segTree [index]. left + segTree [index]. right)> 1;
If (x <= mid)
{
Return segTree [index]. counter + query (index <1) + 1, x );
}
Return segTree [index]. counter + query (index <1) + 2, x );
} 4. Deletion of Line Segment Tree Elements
[Cpp]
Void delete _ (int c, int d, int index)
{
If (c <= segTree [index]. left & d> = segTree [index]. right)
SegTree [index]. counter --;
Else
{
If (c <(segTree [index]. left + segTree [index]. right)/2) delete _ (c, d, segTree [index]. left );
If (d> (segTree [index]. left + segTree [index]. right)/2) delete _ (c, d, segTree [index]. right );
}
}

Void delete _ (int c, int d, int index)
{
If (c <= segTree [index]. left & d> = segTree [index]. right)
SegTree [index]. counter --;
Else
{
If (c <(segTree [index]. left + segTree [index]. right)/2) delete _ (c, d, segTree [index]. left );
If (d> (segTree [index]. left + segTree [index]. right)/2) delete _ (c, d, segTree [index]. right );
}
} IV. Application of Line Segment tree
Maximum Range Query
Dynamic query for continuous interval modification or single-node update
Dynamic query of Multi-Dimensional Space

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.