230 likes | 612 Views
Segment Trees. Extremely versatile. Basic Segment Tree. void add( int pos, int val ); int range_sum ( int start, int end); Three ways below of visualizing it. Commonly stored in an array to save memory. Node i : Parent = i /2, left child = i *2, right child= i *2+1. 31. 9. 22.
E N D
Segment Trees Extremely versatile
Basic Segment Tree • void add(intpos, intval); • intrange_sum(int start, int end); • Three ways below of visualizing it. • Commonly stored in an array to save memory. • Node i: Parent = i/2, left child = i *2, right child= i*2+1 31 9 22 4 5 14 8 3 1 4 1 5 9 2 6 31 31 9 22 9 22 4 5 14 8 4 5 14 8 3 1 4 1 5 9 2 6 3 1 4 1 5 9 2 6
Add/Modify • Add a certain value to bottom node. • Propagate up the tree. • Original segment tree-> • Add 5 to value 5. • New value is 10. • Add 5 to every nodealong the path fromthe bottom node to the root. • Changed nodes arehighlighted. 31 9 22 4 5 14 8 3 1 4 1 5 9 2 6 36 9 27 4 5 19 8 3 1 4 1 10 9 2 6
Add/Modify Code • Note that SIZE is the size of the segment tree (We usually assume it to be a power of 2. You can always pad it with 0s to make it a power of 2). • Also, the tree is stored with the root at node 1, its children at node 2 and 3, and so on… void add(int pos, intval) { //pos is 0-indexed int node = SIZE+pos; while(node > 0) { segTree[node] += val; node /= 2; } }
Range Sum • Sums up the values in a range. • Select O(lgn) nodes to cover the range. • Original segment tree. • Range sum(1,4) • The 3 nodes selected cover the range. • Sum of range is sumof highlighted nodes. 31 9 22 4 5 14 8 3 1 4 1 5 9 2 6 31 9 22 4 5 14 8 3 1 4 1 5 9 2 6
Range Sum Code • Call recursive helper function. int sum(int start, int end) { return sum(1, start, end, 0, SIZE-1); } int sum(int node, int start, int end, int left, int right) { // Case 1: Intervals disjoint if(end<left || right<start) return 0; //Case 2: Current interval inside query interval if(start<=left && right<=end) return segTree[node]; //Case 3: Overlap, recurse on children return sum(node*2, start, end, left, (left+right)/2) + sum(node*2+1, start, end, (left+right)/2+1, right); }
Other operations • For example, find minimum in range. • void add(intpos, intval); • intrange_min(int start, int end); • Add/modify code similar. • Basically, a node’s value needs to be computed in O(1) time from its children. 1 1 2 1 1 5 2 3 1 4 1 5 9 2 6
Lazy Propagation • What if you need to modify a range? • You need to BE LAZY! • Store lazy value for each node. • For updates, find the O(lgn) nodes that cover a range, and set their lazyvalue. • Propagate lazy value tochildren when recursingon child nodes.
Lazy Propagation • Let lazy[node] = value to be added to this interval. • True value of node = segTree[node] + lazy[node] at all times (need to be able to determine true value of node from segTree and lazy in O(1) time). • Example below: Add 5 to range [0,5]. • Highlighted nodes are in range and modified. • Can modify lazy and segTree or only lazy. 31 0 9 22 5 0 4 5 14 8 0 0 5 0 3 1 4 1 5 9 2 6 0 0 0 0 0 0 0 0
Potw • Farmer John has a large field of grass. • Each of the N plots has a certain amount of grass. • Bessie and the other cows choose an interval in which they want to graze. • If Bessie and the cows graze on an interval, the amounts of grass in all plots in that interval are reduced by a certain amount. • The cows can’t graze on an interval if it would cause the amount of grass to turn negative, so Farmer John must stop them. • How many groups of cows does Farmer John need to stop?
Potw • Sample input: • 4 3 • 7 • 3 • 2 • 4 • 1 4 2 • 2 3 1 • 1 2 1 • Sample output: • 1 • Input format: • Line 1: N C (N is the number of plots of grass and C is the number of groups of cows) • Line 2…N+1: G_i: The amount of grass in the i-th plot • Line N+2…N+C+1: A B C (If the cows graze, they decrease the amount of grass of each plot in [A, B] by C) • Output format: • Line 1: A, the amount of groups of cows FJ has to turn away • Constraints: • 1<=N,C<=1,000: 10 points • 1<=N,C<=100,000: 25 points