A segment tree is a binary search tree, similar to an interval tree, which divides an interval into a number of cell ranges, each of which corresponds to a leaf node in a segment tree.
For each non-leaf node in the segment tree [A, b], its left son represents a range of [A, (A+B)/2], and the right son represents a range of [(A+B)/2+1,b]. Therefore, the segment tree is a balanced binary tree, the last number of child nodes is N, that is, the length of the entire segment interval.
The segment tree allows you to quickly find the number of occurrences of a node in several segments, with a time complexity of O (Logn). The spatial complexity of the non-optimized is 2N, so it is sometimes necessary to make space compressed by discretization.
Case: node update, finding minimum value
#1077: RMQ Problem-line tree
Time limit:10000ms
Single point time limit:1000ms
Memory limit:256MB
Describe
Last said: Little hi to small ho out of such a problem: assume the entire shelf from left to right placed N products, and sequentially labeled 1 to N, each small hi gave a section of the interval [L, R], small ho to do is to select the label in this range of all goods weight of the lightest one, And tell little hi the weight of this product. But in the process, the weight of the goods in certain locations may change (for example, the replacement of other kinds of goods) because of the behavior of others.
Little Ho proposed two very simple methods, but none of them could be solved perfectly. So this time, in the face of a bigger data size, what will little ho be good for?
Hint: actually just less than St to calculate some of the interval only
Input
Each test point (input file) has and has only one set of test data.
The 1th behavior of each set of test data is an integer n, meaning as described earlier.
The 2nd behavior of each group of test data n integers, respectively, describes the weight of each commodity, where the I integer represents the weight of the commodity labeled I weight_i.
The 3rd behavior of each set of test data is an integer q, which indicates the sum of the number of times that a small hi has been queried and the number of times the weight of the product has been changed.
Each group of test data n+4~n+q+3 line, each line describes an operation, each line begins with a number belonging to 0 or 1, respectively, indicating that the line describes a query and describe the weight of a product change two cases. For line n+i+3, if the line describes a query, then the next two integers are Li, RI, which represents a range of small hi queries [Li, Ri]; If the line describes a change in the weight of a product, then two integer pi,wi, indicating that the weight of the product with the position number pi is changed to Wi
For 100% of data, meet N<=10^6,q<=10^6, 1<=li<=ri<=n,1<=pi<=n, 0<weight_i, wi<=10^4.
Output
For each set of test data, for each small hi query, according to the order in which they appear in the input, each output line represents the result: the weight of the lightest item in all the items in the interval [Li, Ri].
AC Code:
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <list>
#include <iterator>
#include <string>
#include <stack>
using namespace Std;
#define INF 0X3FFFFFFF
const int MAX = 100000100;
struct NODE {
int value, left, right;
}node[max];
void Buildtree (int n, int left, int. right) {
Node[n].left = left;
Node[n].right = right;
if (left = = right)
{
scanf ("%d", &node[n].value);
Return
}
int mid = (left + right) >> 1;
Buildtree (n << 1, left, mid);
Buildtree ((n << 1) + 1, Mid + 1, right);
Node[n].value = min (node[n << 1].value, node[(n << 1) + 1].value);
}
int findtree (int n, int begin, int end) {
int p1 = inf, p2 = INF;
if (node[n].left >= begin&&node[n].right <= end)
return node[n].value;
if (Begin <= node[n << 1].right)
P1 = Findtree (n << 1, begin, end);
If (end >= node[(n << 1) + 1].left)
P2 = Findtree ((n << 1) + 1, begin, end);
return min (p1, p2);
}
void Updatetree (int n, int ind, int val) {
if (Node[n].left = = node[n].right)
{
Node[n].value = val;
}
Else
{
if (Ind <= node[n << 1].right)
Updatetree (n << 1, Ind, Val);
if (Ind >= node[(n << 1) + 1].left)
Updatetree ((n << 1) + 1, Ind, Val);
Node[n].value = min (node[n << 1].value, node[(n << 1) + 1].value);
}
}
int main ()
{
int N;
int m;
int S, l, R;
while (~SCANF ("%d", &n))
{
Buildtree (1, 0, N-1);
scanf ("%d", &m);
for (int i = 0; i < m; i++)
{
scanf ("%d%d%d", &s, &l, &r);
if (s = = 0)
{
printf ("%d\n", Findtree (1, L-1, r-1));
}
if (s = = 1)
{
Updatetree (1, L-1, R);
}
}
}
return 0;
}
The key to the problem of AC is not the line tree algorithm, but the standard input and output, if using C + + cin and cout must time out.
Reason:
SCANF is the formatted input, and printf is the formatted output. CIN is the input stream, cout is the output stream. The efficiency is slightly lower, but the writing is simple.
Root cause Baidu has explained, OJ generally use scanf and printf better!
This article is from the "Snow Night Star" blog, please make sure to keep this source http://592669550.blog.51cto.com/5487419/1700520
Tree-line Segment tree