POJ--3264 line segment tree, poj3264 Line Segment
Question:
Enter two numbers (m, n), m indicates the number of cattle heads, and n indicates the number of queries.
Enter two numbers (x, y) for the query, indicating the start value and end value of the query range. The query result is: the maximum weight of the ox in this range minus the minimum weight of the ox, the complexity of each query is 1000,000.
For example,
Input:
6 31734251 54 62 2
Output:
630
Analysis: This question is a typical space-to-time question. We should think of the Line Segment tree as soon as we can see it. Here is a blog about the line segment tree that I think is well written: http://www.cnblogs.com/shuaiwhu/archive/2012/04/22/2464583.html.
1. Create a line segment tree based on the input m value. Public void buildTree (int m)
2. initialize the line segment tree based on the weight of the input cattle. Public void initTree (SNode sn, int value)
3. query the line segment tree based on the query. Public void find (SNode sn, int a, int B)
First, let's look at building a line segment tree. Because the maximum and minimum values to be queried are different, each node in the online segment tree must store the Left and Right thresholds of the range and reference of the left and right subnodes, it also stores the maximum and minimum values in this range. Take the six cows as an example and set the number to 1-6. The final constructed line segment tree should be shown in:
Analyze the build recursion process.
First, the termination condition is: first = last (taking Node 1 as an example, first = 1, last = 1 );
The common recursive operation is to assign values for first and last in the node, indicating the range of the node, that is
Node. first = first, node. last = last;
Next, let's look at recursive parameters: according to the previous analysis, we can see that there must be a node referenced by the node, and there must be a node range, that is, first and last;
Finally, let's look at the recursion process: the recursion process is nothing more than the left and right subtree recursion, that is:
node.left = new SNode();node.right = new SNode();build(node.left, first, ( first + last) / 2);build(node.right, ( first + last) / 2 + 1, last);
Note: Why do we assign a value to the reference of the left and right subnodes first? in java, if no value is given first, no pointing address is assigned. After passing the parameter, whether to assign values to parameters. After the return result, the original node still points to null. Analyze the process of passing this value:
The process of node1 first new is equivalent to node1 pointing to the node in the heap first, then node1 copying to node2, node2 also pointing to node, therefore, using node2 to modify node and node1 will have the same effect.
After understanding the process of building a line segment tree, the process of initializing the line segment tree and searching is similar. I will not go into details here. Let's go directly to the code.
Code:
package study;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.StringTokenizer;/** * http://poj.org/problem?id=3264
* Enter two numbers (m, n), m indicates the number of cattle heads, and n indicates the number of queries. * The query structure is as follows (x, y). The maximum weight minus the minimum weight is the query result. The complexity of each query is and. ** @ Author cnx * @ CreateDate; September 28, 2014 9:38:25 */public class SegmentTree {public static void main (String [] args) throws IOException {SegmentTree s = new SegmentTree (); bufferedReader stdin = new BufferedReader (new InputStreamReader (System. in); String line = stdin. readLine (); StringTokenizer st = new StringTokenizer (line); s. m = Integer. parseInt (st. nextToken (); s. n = Integer. parseInt (st. nextToken (); // build and initialize node s. buildTree (s. m); for (s. inc = 1; s. inc <= s. m; s. inc ++) {line = stdin. readLine (); st = new StringTokenizer (line); int value = Integer. parseInt (st. nextToken (); s. initTree (s. sn, value) ;}// enter the query and give the result for (int I = 0; I <s. n; I ++) {line = stdin. readLine (); st = new StringTokenizer (line); int a = Integer. parseInt (st. nextToken (); int B = Integer. parseInt (st. nextToken (); s. max = 0; s. min = 99999999; s. find (s. sn, a, B); System. out. println (s. max-s.min) ;}} public int m; public int n; public SNode sn = new SNode (); public int inc; public int max; public int min; /*** line segment Tree node class * @ author cnx * @ CreateDate; September 29, 2014 9:17:55 */public static class SNode {int first; int last; int max; int min = 9999999; SNode left; SNode right;}/*** construct a line segment tree * @ param m range: 1-m */public void buildTree (int m) {build (sn, 1, m);}/*** build the recursive function of the Line Segment tree * @ param node * @ param L first in the line segment Tree node, that is, the left threshold of the range * @ last in the param R node, that is, the right threshold of the range */public void build (SNode node, int L, int R) {if (node = null) node = new SNode (); node. first = L; node. last = R; if (L = R) {return;} node. left = new SNode (); node. right = new SNode (); build (node. left, L, (L + R)/2); build (node. right, (L + R)/2 + 1, R );} /*** assign values to the max and min fields of the line tree * @ param sn * @ param value input value */public void initTree (SNode sn, int value) {if (value> sn. max) {sn. max = value;} if (value <sn. min) {sn. min = value;} if (sn. first = sn. last) {return;} if (inc> (sn. last + sn. first)/2) {initTree (sn. right, value);} else {initTree (sn. left, value) ;}/ *** search in the online segment tree, the maximum and minimum values of a-B * @ param sn * @ param a * @ param B */public void find (SNode sn, int a, int B) {if (sn. first = a & sn. last = B) {if (sn. max> max) {max = sn. max;} if (sn. min <min) {min = sn. min;} return;} if (B <= (sn. first + sn. last)/2) {find (sn. left, a, B);} else if (a> (sn. first + sn. last)/2) {find (sn. right, a, B);} else {find (sn. left, a, (sn. first + sn. last)/2); find (sn. right, (sn. first + sn. last)/2 + 1, B );}}}
Poj 3264 line segment tree ~~~ Question: http: // pojorg/problem? Id = 3264
Your thinking is messy.
# Include "stdio. h"
Const int MAX = 50010;
Struct Tree
{
Int max, min, l, r;
Int mid () {return (l + r)> 1 ;}
} Node [MAX * 4];
Int a [MAX];
Void clr (int l, int r, int tag)
{
Int mid = (l + r)> 1;
Node [tag]. l = l;
Node [tag]. r = r;
If (l + 1 = r)
{
Node [tag]. max = node [tag]. min = a [l];
Return;
}
Clr (l, mid, tag <1 );
Clr (mid, r, (tag <1) + 1 );
Node [tag]. max = node [1 + (tag <1)]. max;
If (node [tag <1]. max> node [1 + (tag <1)]. max)
{
Node [tag]. max = node [tag <1]. max;
}
Node [tag]. min = node [1 + (tag <1)]. min;
If (node [tag <1]. min <node [1 + (tag <1)]. min)
{
Node [tag]. min = node [tag <1]. min;
}
}
Int queryMax (int l, int r, int tag)
{
Int mid = node [tag]. mid ();
Int a, B;
If (l <= node [tag]. l & node [tag]. r <= r)
{
Return node [tag]. max;
}
If (r <= mid) return queryMax (l, r, tag <1 );
Else if (l> = mid) return queryMax (l, r, 1 + (tag <1 ));
Else
{
A = queryMax (l, mid, tag <1 );
B = queryMax (mid, r, 1 + (tag <1 ));
If (a <B) a = B;
Return;
}
}
Int queryMin (int l, int r, int tag)
{
Int mid = node [tag]. mid ();
Int a, B;
If (l <= node [tag]. l & node [tag]. r <= r)
{
Return node [tag]. min;
}
If (r <= mid) return queryMin (l, r, tag <1 );
Else if (l> = mid) return queryMin (l, r, 1 + (tag <1 ));
Else
{
A = queryMin (l, mid, tag <1 );
... The remaining full text>
Line Segment tree on POJ
Sometimes I have to look at the specific question. I usually don't care how big the array can be, but it is about time rather than space. I think it may be for the sake of discretization or other aspects .. For a line segment tree, only one dimension is written. For a perimeter tree, the area tree has not been written yet ..
LZ don't mind too much. I can't help but say a few words when I see that I am a fan of poj ..