Segment Tree Classic operation template (single point update, replacement; interval update, substitution; interval summation max.)

Source: Internet
Author: User

For a segment tree, the following is a list of some of the most commonly used operations in the segment tree application. (The specific topic is not posted, only for a certain basis of reference code style)

In addition, note that multiple sets of input to write scanf ("%d%d", &n,&m)!=eof, line segment tree of the problem must be in C language input and output, To use a character array, no strings, enter characters when you want to add getchar() to devour empty lines .

(1) Single point increase or decrease, interval summation:

#include <iostream> #include <stdio.h> #include <string> #include <string.h>using namespace std int a[50000*4];//Open four times times can int sum[50000*4];int T,n,b,c,ans;char s[20];//single point increment, interval sum int build (int l,int r,int o)//l left, R right, o node { if (l==r)//from top to bottom build return sum[o]=a[l];else{int mid=l+ (r-l)/2;return sum[o]=build (l,mid,2*o) +build (mid+1,r,2*o+1);}} void query (int l,int r,int o)//b,c is the interval to sum {if (B&LT;=L&AMP;&AMP;C&GT;=R)//Note B,c contains l,r ans+=sum[o];else{int mid=l+ (r-l)    /2;if (b<=mid) query (l,mid,o*2); if (c>mid) query (mid+1,r,2*o+1);}  }void Add (int l,int r,int o) {sum[o]+=c;//Note the value to be added if (l==r) return;else{int mid=l+ (R-L)/2;  if (b<=mid) Add (l,mid,o*2); else Add (mid+1,r,o*2+1);}} int main () {int ca=1;scanf ("%d", &t), while (t--) {scanf ("%d", &n), for (int i=1;i<=n;i++) scanf ("%d", &a[i] );p rintf ("Case%d:\n", ca++), Build (1,n,1), and while (scanf ("%s", s)) {if (s[0]== ' E ') break;if (s[0]== ' A ') {scanf ("%d%d", &AMP;B,&AMP;C); add (1,n,1);} if (s[0]== ' s ') {scanf ("%d%d", &b,&c); C=-c;add (1,n,1);} If(s[0]== ' Q ')    {ans=0;scanf ("%d%d", &b,&c); query (1,n,1); printf ("%d\n", ans);}} return 0;

(2) Single point update, interval to find the most value

int build (int l,int r,int o)//l left, R right, o node {if (l==r)//top-down contribution return max1[o]=a[l];//Max Else{int mid=l+ (r-l)/2;return max1[ O]=max (Build (L,mid,2*o), build (mid+1,r,2*o+1)); }}void Update (int l,int r,int O)//single point update {//sum[o]+=c;    Max1[o]=max (max1[o],c);//the largest if (l==r) return;else{  int mid=l+ (R-L)/2 between the original value and the changed value;  if (b<=mid)  update (l,mid,o*2);  else  update (mid+1,r,o*2+1);}} The void query (int l,int r,int o)//b,c is the interval {if (b<=l&&c>=r) that requires maximum value//Note that b,c contains l,r Ans=max (Ans,max1[o]); Ans Initial value is 0//ans+=sum[o];else{int mid=l+ (r-l)/2;if (b<=mid) query (l,mid,o*2);    if (c>mid) query (mid+1,r,2*o+1);} }

(3) interval substitution, interval summation

#include <iostream> #include <stdio.h>using namespace Std;const int Max_n=100100;int sum[max_n<<2], Col[max_n<<2];int n,q,x,y,c;void push_down (int l,int r,int O)//devolve {int m= (l+r) >>1;if (Col[o]) {col[o< <1]=col[o<<1|1]=col[o];sum[o<<1]= (m-l+1) *col[o];sum[o<<1|1]= (r-m) *col[o];col[o]=0;} void build (int l,int r,int o) {col[o]=0;sum[o]=1;if (l==r) return; int m= (L+R) >>1;build (l,m,o<<1); Build (m+1 , r,o<<1|1); sum[o]=sum[o<<1]+sum[o<<1|1];} void update (int l,int r,int o) {int m= (l+r) >>1;if (x<=l&&r<=y) {col[o]=c;sum[o]= (r-l+1) *c;return;} Push_down (L,r,o); if (x<=m) update (L,M,O&LT;&LT;1); if (y>m) update (M+1,R,O&LT;&LT;1|1); sum[o]=sum[o<<1] +SUM[O&LT;&LT;1|1];} int main () {int t,cas=1;scanf ("%d", &t), while (t--) {scanf ("%d%d", &n,&q), Build (1,n,1), while (q--) {scanf ("   %d%d%d ", &x, &y, &c); Update (1,n,1);} printf ("Case%d:the total value of the hook is%d.\n", cas++, Sum[1]);} return 0;} 

(4) interval update, Interval summation

#include <iostream> #include <cstdio>using namespace std; #define N 100005__int64 sum[n << 2];__int64 Mark[n << 2];__int64 basic_num[n<<2];inline void pushup (int o) {Sum[o] = Sum[o << 1] + sum[o <&lt ; 1 | 1];} void pushdown (int o, int len) {if (Mark[o]) {///because the son node of O may be marked by multiple delays, and the delay mark of the son node of O is not moved to the grandson node O, so use "+ =" mark[        o << 1] + = Mark[o];        Mark[o << 1 | 1] + + mark[o];        /* This is used Mark[o] multiplied by the interval length, not mark[o<<1], because O's son node, if marked repeatedly, has been updated for Sum[o<<1].         */Sum[o << 1] + = mark[o] * (Len-(Len >> 1));        Sum[o << 1 | 1] + = mark[o] * (len >> 1); Mark[o] = 0;    After moving the tag to the son node, the parent node's delay tag is stripped of the}}void build (int l, int r, int o) {Mark[o] = 0;        if (L = = r) {Sum[o]=basic_num[l];    Return    } int m = (L + r) >> 1;    Build (L, M, O << 1);    Build (M + 1, R, o << 1 | 1); Pushup (o);//sum value Initialization}void update (int L, int R,__int64 c, int l, int r, int o)//l,r is the interval to update {if (L >= l && R <= R) {Mark[o] + = C;        Sum[o] + = c * (r-l + 1);    Return }/* When you want to update the son node of this interval marked by delay, first move the delay tag to the son node of course, if the son node of the paragraph has not been updated, the delay tag does not need to move to the son node, so that the time complexity of the update operation is still O (Logn), but also using the delay tag    The reason. */Pushdown (o, r-l + 1);    Decentralize the existing delay int m = (L + r) >> 1;    if (M >= l) Update (L, R, C, L, M, O << 1);    if (M < R) Update (L, R, C, M + 1, R, o << 1 | 1); Pushup (o);}    __int64 query (int l, int r, int l, int r, int o) {if (L >= l && R <= R) return Sum[o];    To fetch the value of the O child node, the delay mark of O is also moved downward Pushdown (o, r-l + 1);    int m = (L + r) >> 1;    __int64 ret = 0;    if (M >= l) ret + = query (l, R, L, M, O << 1);    if (M < r) ret + = query (L, R, M + 1, R, o << 1 | 1); return ret;}    int main () {int n, q, A, B;    __int64 C;    Char op;    scanf ("%d%d", &n,&q); for (int i=1;i<=n;i++) scanf ("%i64d", &basIc_num[i]);    Build (1, N, 1);        while (q--) {GetChar ();        scanf ("%c%d%d", &op, &a, &b);        if (op = = ' Q ') printf ("%i64d\n", query (A, B, 1, N, 1));            else {scanf ("%i64d", &c);        Update (A, B, C, 1, N, 1); }} return 0;}


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Segment Tree Classic operation template (single point update, replacement; interval update, substitution; interval summation max.)

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.