Introduction to the HDU 1754 line segment tree

Source: Internet
Author: User

At first, I thought that this question was submitted, and there were a lot of AC people who thought it was a water question. I used the simplest method to operate it and timed out!

Line Segment 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.

Practical Application: (from Baidu encyclopedia)

The simplest application is to record whether a line segment has been overwritten and query the total length of the currently overwritten line segment at any time. In this case, an int count variable can be added to the node structure, representing the overlay line segment length and in the subtree represented by the current node. In this case, the Count value is maintained in the insert (delete), so the current total overwrite value is the Count value of the root node.

In addition, you can replace count with bool cover to find whether a node or line segment is overwritten.[1]

In fact, by recording different data on the node, the line segment tree can complete many different tasks. For example, if each insert operation adds K to each position of a line segment and the query operation calculates the sum of a line segment, the value to be recorded on the node is sum.

There is a problem: to keep all sum values correct, each insert operation may update O (n) sum values, this degrades the time complexity to O (n ).

The solution is lazy thought: For the wholeEndThe operations performed by the vertex are marked on the node rather than actually executed until they are divided into two parts based on the needs of the query operation.

According to the lazy idea, we can add a value toadd on the node that does not represent the original line segment, that is, the sum of the K values of the insert operation to be executed in the future. During the insertion of the entire node, only the sum and toadd values are updated without going down, so that the time complexity can be identified as O (logn ).

When you query a node whose toadd value is 0, the sum value stored in the node is directly returned. If you query a part whose toadd value is not 0, then, update the sum value of the left and right subnodes, pass the toadd value, and then recursion the Left and Right subnodes on the query itself. The time complexity is also O (logn ).


# Include <iostream> using namespace STD; struct node {int L, R, mid, Max;} node [600000]; void Init (int A, int B, int N) {node [N]. L = A; node [N]. max =-1; node [N]. R = B; node [N]. mid = (a + B)/2; if (a + 1 = B) return; Init (A, (A + B)/2, N * 2 ); init (A + B)/2, B, 2 * n + 1);} void Update (INT POs, int value, int N) {If (value> node [N]. max) node [N]. max = value; If (node [N]. L + 1) = node [N]. r) return; If (Pos <node [N]. mid) {Update (Pos, value, 2 * n);} If (Pos> = node [N]. mi D) {Update (Pos, value, 2 * n + 1) ;}} int query (int A, int B, int N) {If (node [N]. L = A & node [N]. R = B) Return node [N]. max; if (a <node [N]. mid) {If (B <= node [N]. mid) {return query (A, B, 2 * n);} else {return max (query (A, node [N]. mid, 2 * n), query (node [N]. mid, B, 2 * n + 1) ;}} else {return query (A, B, 2 * n + 1) ;}} int main () {int N, m, T, A, B, I; char ch; while (CIN> N> m) {Init (1, n + 1, 1); for (I = 1; I <= N; I ++) {scanf ("% d", & T); Update (I, T, 1) ;}for (I = 1; I <= m; I ++) {getchar (); CIN> CH; CIN> A> B; If (CH = 'q') cout <query (, B +) <Endl; // note that B + 1 is not B. Because the line segment tree is a left open right closed interval. Elseupdate (A, B, 1) ;}} return 0 ;}

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.