Segment trees are often seen in some ACM topics, and this data structure is mainly used in computational geometry and geographic information systems. is a segment tree:
PS: You may have seen different representations of line trees, but they are all the same, built on your own needs. )
1. Segment tree basic properties and operation
The line segment tree is a binary tree, denoted by T (A, B), and the parameter A, a, is the interval [a, a], where b-a is called the length of the interval, denoted as L.
The Segment Tree T (A, B) can also be recursively defined as:
If l>1: [A, (a+b) Div 2] is the left son of T; [(A+b) Div 2,b] is the right son of T. If the l=1:t is a leaf node.
The nodes in the segment tree generally take the following data structures:
struct node{ int left,right; Interval value Node *leftchild; Node *rightchild; };
Establishment of Segment tree:
Node *build (int l, int R)//build two fork Tree { node *root = new Node; Root->left = l; Root->right = R; Set node interval root->leftchild = NULL; Root->rightchild = NULL; if (l +1< r) { int mid = (r+l) >>1; Root->leftchild = Build (L, mid); Root->rightchild = Build (mid , R); } return Root;}
segment Insertion and deletion in a segment tree :
Add a cover field to calculate the number of times a segment is overwritten, so you should set the cover to 0 when creating a two-fork tree.
Insert a line segment [C,d]:
void Insert (int c, int d, Node *root) { if (c<= root->left&&d>= root->right) Root-> cover++; else { if (C < (root->left+ root->right)/2) Insert (c,d, Root->leftchild ); if (d > (root->left+ root->right)/2) Insert (c,d, Root->rightchild );
Delete a line segment [C,d]:
void Delete (int c, int D, Node *root) { if (c<= root->left&&d>= root->right) c18/>root-> cover= root-> cover-1; else { if (C < (root->left+ root->right)/2) Delete (c,d, Root->leftchild ); if (d > (root->left+ root->right)/2) Delete (C,d, root->rightchild);
2. Application of Segment Tree
Each node in a segment tree tends to add some additional fields. Some of the dynamic maintenance information is stored in these domains, depending on the situation. These fields make the segment tree extremely flexible and adaptable to different requirements.
Example one:
A few boxes were scattered on the table, and the rear of the table was a wall. Now a beam of parallel light is coming from the front of the table and the shadow of the box is projected onto the wall. Q What is the total width of the shadow?
This title is a classic model. Here, we omit some of the processing steps, direct analysis of the key issues, you can abstract the topic as follows: There are several lines on the x-axis, to find the total length of the segment coverage, that is, the length of the s1+s2.
2.1 Most Direct procedure:
Set the line segment coordinate range to [Min,max]. Use a one-dimensional array with a subscript range of [min,max-1], where the element I of the array represents the interval of [i,i+1]. Array element initialization is all 0. For each segment that is [A, b], all the corresponding array elements in [A, b] are set to 1. Finally, the number of 1 in the array can be counted.
Initial 0 0 0 0 0[1,2] 1 0 0 0 0[3,5] 1 0 1 1 0[ 4,6] 1 0 1 1 1[5,6] 1 0 1 1 1
The disadvantage is that the time complexity is determined by the square of the subscript range, when the current scale is very large ([0,10000]), this method is too inefficient.
2.2 Discretization of the procedure:
Basic idea: First to order all the endpoint coordinates from small to large, the coordinate value corresponding to its ordinal one by one. This allows the original coordinate value to be converted to a sequence number, applying the previous algorithm to it, and then converting the final result back to the solution. This method is valid for cases where the number of segments is relatively small.
Example:
[10000,22000] [30300,55000] [44000,60000] [55000,60000]
Sort of 10000,22000,30300,44000,55000,60000.
Corresponds to 1, 2, 3, 4, 5, 6
then [3,5] [4,6] [5,6]
Initial 0 0 0 0 0[1,2] 1 0 0 0 0[3,5] 1 0 1 1 0[ 4,6] 1 0 1 1 1[5,6] 1 0 1 1 1
10000,22000,30300,44000,55000,60000
1, 2, 3, 4, 5, 6
(22000-10000) + (60000-30300) =41700
The time complexity of this method is determined by the square of the number of segments, which is too inefficient for cases where the number of segments is large.
2.3 Using the line segment tree:
Adds a domain cover to each node in the segment tree. Cover=1 indicates that the corresponding interval of the node is completely covered, and cover=0 indicates that the corresponding interval of the node is not fully covered.
Segment tree, add segment [1,2][3,5][4,6]
Insert algorithm:
void Insert (Node *root, int A, int b) { int m; if (root->cover = = 0) { m = (root->left+ root->right)/2; if (a = = Root->left && b = = root->right) root->cover =1; else if (b <= m) Insert (Root->leftchild, A, b); else if (a >= m) Insert (Root->rightchild, A, b); else { Insert (Root->leftchild, A, m); Insert (Root->rightchild, M, b);}}}
Statistical algorithms:
int Count (Node *root) { int m,n; if (Root->cover = = 1) return (root-> right-root-> left); else if (root-> right-root-> left== 1) return 0; m= Count (root->leftchild); n= Count (root->rightchild); return m+n;}
Line segment Trees (segment tree)