Segment Tree tutorial (data structure, C + +)

Source: Internet
Author: User

Statement :

Only one picture reproduced in http://www.cnblogs.com/shuaiwhu/archive/2012/04/22/2464583.html, oneself painting too troublesome ... That blog is also very good explanation, but he used a pointer to define the line segment tree, and I used the structure, and he spoke of the line segment tree more advanced operations, if the line tree of the primary operation does not understand, please continue to read

As a very common data structure, segment tree is widely used in Noip and Noi, so the segment tree is briefly explained here.

The segment tree supports summation of a sequence, single-point modification, maximum (max, min), Interval modification (requires lazy marking, not explained). These kinds of operations, time complexity is (LOGN) level, is a very good data structure. Therefore, it has been widely used.

definition : As the name implies, it is a tree structure, but each paragraph is not a point of the usual learning of a point of the tree, but a line of lines, each segment contains a number of values, the most important of which is the start and end points are recorded as L,r that is the left and right endpoints.

So how do you divide the line tree? We use the idea of two points, that is, each time we take a half, then the next operation, so that the ease of operation and the complexity of time. Because the segment tree is derived from two points, the segment tree is a binary tree. This also facilitates the search for the son. Below is a diagram of the line tree, which is useful for understanding:

achievements : Only know the model is not enough, the process of achievement is the key line tree (build (1,1,n)) from the beginning, the left is 1, the right side is n

Bit operation i<<1 equivalent to I/2 (i<<1) | | | is equivalent to i/2+1 acceleration ...

InlinevoidUpdateinti) Update the values maintained by the I node (SUM, Max ...) ) {Node[i].sum=node[i<<1].sum+node[(i<<1)|1].sum; Node[i].maxx=max (node[i<<1].maxx,node[(i<<1)|1].maxx); }inlinevoidBuildintIintLintR//Inline or acceleration{NODE[I].L=l;node[i].r=r;//the left and right endpoints are current recursion to the L and R       if(L==R) {//if l==r, then the current tree node is a real point .NODE[I].MAXX=A[L];//The maximum value is the value of itselfNODE[I].SUM=A[L];//and the value of the interval is itself.        return; }       intMid= (L+R)/2;//because it's a two-prong tree, the midpoint is the split point.Build (i<<1, L,mid);//according to the knowledge of the binary tree, the left son is i/2 right son is i/2+1Build ((i<<1)|1, mid+1, R); Update (i);}

Sequence sum: This is a typical algorithm of line-segment tree, and many other applications are converted from it.

To sum up we define a function sum (int i, int l, int r) i is the starting tree node, we default to 1. L is the starting point of the interval, the label of which is the label in the sequence, andR is the rest of the end point with l. Post code:

InlineintSumintIintLintR//Inline is also accelerating{                                                   if(node[i].l==l&&node[i].r==R)returnNode[i].sum;//if the left and right intervals of the tree node are the same as the lookup interval, returns the sum maintained  intMid= (NODE[I].L+NODE[I].R)/2;//determine the midpoint of the tree node to determine whether to continue looking for the left son or the right son  if(R<=mid)returnSUM (i<<1, l,r);//if the right end of the search interval is less than the midpoint, the interval is completely contained in the left son    Else if(L>mid)returnSum ((i<<1)|1, l,r);//the left end is greater than the midpoint, find the right son      Else returnSUM (i<<1, L,mid) +sum ((i<<1)|1, mid+1, R)//If you cross the midpoint, find the left son L to mid, and the right son's mid+1 to R and return the value}

interval to calculate the maximum and interval sum is roughly the same, see for yourself

InlineintMax (intIintLintR) {    if(node[i].l==l&&node[i].r==R)returnNode[i].maxx; intMid= (NODE[I].L+NODE[I].R)/2; if(R<=mid)returnMax (i<<1, L,r); Else if(L>mid)returnMax ((i<<1)|1, L,r); Else returnMax (Max (i<<1, L,mid), Max ((i<<1)|1, mid+1, R));}

single-point update : Different from the interval, but the basic idea is the same.

InlinevoidAddintIintKintV//The currently calculated point is I, which adds the K element in the sequence to V{    if(node[i].l==k&&node[i].r==k) {//the left and right endpoints are equal to K because of the changed single pointnode[i].sum+=v; Node[i].maxx+=v; return; }    intMid= (NODE[I].L+NODE[I].R)/2; if(k<=mid) Add (i<<1, k,v);//if K is less than Mid, K is record in tree node I     ElseAdd (i<<1)|1, k,v);//converselyUpdate (i);//Update}

Finally put down all the code basically can do template.

#include <iostream>#include<cstdio>using namespacestd;structtree{intL,r,sum,maxx;}; Tree node[ -];intn,m,a[ -];inlinevoidUpdateinti) {Node[i].sum=node[i<<1].sum+node[(i<<1)|1].sum; Node[i].maxx=max (node[i<<1].maxx,node[(i<<1)|1].maxx);} InlinevoidBuildintIintLintR) {NODE[I].L=l;node[i].r=R; if(l==R) {Node[i].maxx=A[l]; Node[i].sum=A[l]; return; }     intMid= (L+R)/2; Build (I<<1, L,mid); Build ((I<<1)|1, mid+1, R); Update (i);} InlinevoidAddintIintKintv) {    if(node[i].l==k&&node[i].r==k) {Node[i].sum+=v; Node[i].maxx+=v; return; }    intMid= (NODE[I].L+NODE[I].R)/2; if(k<=mid) Add (i<<1, k,v); ElseAdd (i<<1)|1, k,v); Update (i);} InlineintSumintIintLintR) {    if(node[i].l==l&&node[i].r==R)returnnode[i].sum; intMid= (NODE[I].L+NODE[I].R)/2; if(R<=mid)returnSUM (i<<1, L,r); Else if(L>mid)returnSum ((i<<1)|1, L,r); Else returnSUM (i<<1, L,mid) +sum ((i<<1)|1, mid+1, R);} InlineintMax (intIintLintR) {    if(node[i].l==l&&node[i].r==R)returnNode[i].maxx; intMid= (NODE[I].L+NODE[I].R)/2; if(R<=mid)returnMax (i<<1, L,r); Else if(L>mid)returnMax ((i<<1)|1, L,r); Else returnMax (Max (i<<1, L,mid), Max ((i<<1)|1, mid+1, R));}intMain () {scanf ("%d%d",&n,&m);  for(intI=1; i<=n;i++) scanf ("%d",&A[i]); Build (1,1, N);  for(intI=1; i<=m;i++){        intc,a,b; scanf ("%d%d%d",&c,&a,&b); if(c==1) printf ("%d\n", SUM (1, A, b)); Else if(c==2) Add (1, A, b); Else if(c==3) printf ("%d\n", Max (1, A, b)); }    }

Segment Tree tutorial (data structure, C + +)

Related Article

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.