Main Topic
A sequence, each operation can be an interval number is added to the same integer, can also be asked for a range of all numbers and. (The interval here refers to a number of successive numbers in the sequence) and gives the result for each query.
Ideas
For interval Lookup update operations, consider using data structures such as stretch trees, segment trees, and so on. This is solved by using a line segment tree. It is important to note that for an increment of an interval, the lazy method is resolved if each time it goes to the leaf node to update it, it must time out. That is, if you can get the required information from the current node, you do not have to go to the child node.
Implementation (c + +)
#define_crt_secure_no_warnings#include<iostream>#include<stdio.h>using namespacestd;#defineMax_count 100005#defineMAX (A, b) a>b? A:b#defineMIN (A, b) a<b? A:b//find the sum length of two intersecting intervals (that is, the total length covered by two intervals)intInterval (intBEG1,intEnd1,intBEG2,intEnd2) { intTMP =MAX (End1, End2); //be careful not to MAX (End1, End2)-min (BEG1, BEG2) because this is done at compile time when the macro definition expands,//with the three mesh operator, the precedence results in an Error!!!! tmp-=MIN (BEG1, BEG2); return(END1-BEG1 + END2-BEG2)-tmp +1;}intGnumcount, Gquerycount;//number of total numbers, total number of queries intGnumber[max_count];//array of Segment tree nodes//Definition of Segment tree nodestructtreenode{intBegin//the node covers the left edge of the interval intEnd//the node covers the right edge of the interval Long LongSum//This node overwrites the current sum value of the interval, excluding those values that Inc may have added (that is, the actual and should be sum + inc * (END-BEGIN+1) Long LongInc;//the node that covers those points in the interval should be incremented (note that all points in that interval)};structTreeNode gtreenodes[max_count*4];//bottom-up update that adds the sum value of the left and right child to the sum value of the nodevoidPushup (intNode_index) { intLeft_child =2* Node_index +1; intRight_child =2* Node_index +2; Gtreenodes[node_index].sum= Gtreenodes[left_child].sum +gtreenodes[right_child].sum;}//top-down update operation, when the node can not be fully covered by the query interval, you need to go down, to its child node location to query//before querying, the INC value needs to be passed to the child node, and the sum value of the node is updated, Inc value clear 0voidPushdown (intNode_index) {TreeNode* node = gtreenodes +Node_index; intLeft_child =2* Node_index +1; intRight_child =2* Node_index +2; Node->sum + = node->inc* (Node->end-node->begin +1); Gtreenodes[left_child].inc+ = Node->Inc; Gtreenodes[right_child].inc+ = Node->Inc; Node->inc =0;}voidBuildtree (intNode_index,intBegintend) {TreeNode* node = gtreenodes +Node_index; Node->inc = Node->sum =0; Node->begin =Beg; Node->end =end; if(Beg = =end) {Node->sum =Gnumber[beg]; return; } intMid = (beg + end)/2, Left_child =2* Node_index +1, Right_child =2* Node_index +2; Buildtree (Left_child, Beg, mid); Buildtree (Right_child, Mid+1, end); //update from bottom uppushup (Node_index);}voidADD (intNode_index,intBegintEndLong Longc) {TreeNode* node = gtreenodes +Node_index; intLeft_child =2* Node_index +1, Right_child =2* Node_index +2, Mid = (Node->begin + node->end)/2; if(Node->begin > End | | node->end <Beg) { return; } //If the current node is fully covered by the query interval, it is not passed down and the INC value is increased directly if(Node->begin >= Beg && node->end <=end) {Node->inc + =C; return; } //If the node cannot be completely overwritten by the query interval, the split node needs to be passed down, and the sum value needs to be increased (the length of the coincidence between the INC * two intervals)//While the Inc value remains unchangedNode->sum + = (Interval (node->begin, Node->end, Beg, end) *c); intEnd1 =MIN (end, mid); intBEG1 = MAX (Beg, Mid +1); Add (Left_child, Beg, End1, C); ADD (Right_child, BEG1, end, c);}Long LongQuerysum (intNode_index,intBegintend) {TreeNode* node = gtreenodes +Node_index;//printf ("node%d ' s sum =%d\n", Node_index, gtreenodes[node_index].sum);//printf ("Node->beg =%d, Node->end =%d, beg =%d, end =%d\n", Node->begin, Node->end, Beg, end); intLeft_child =2* Node_index +1, Right_child =2* Node_index +2, Mid = (Node->begin + node->end)/2; Long Longsum =0; if(Node->begin > End | | node->end <Beg) { returnsum; } if(Node->begin >= Beg && node->end <=end) {Sum+ = (node->sum + node->inc* (Node->end-node->begin +1)); } Else{ //Split-down update operationpushdown (Node_index); intEnd1 =MIN (end, mid); intBEG1 = MAX (Beg, Mid +1); Long LongSum_left =querysum (Left_child, Beg, end1); Long LongSum_right =querysum (Right_child, BEG1, end); Sum+ = (Sum_left +sum_right); } returnsum;}intMain () {scanf ("%d%d", &gnumcount, &gquerycount); for(inti =0; i < Gnumcount; i++) {scanf ("%d", Gnumber +i); } buildtree (0,0, Gnumcount-1); Charop; intA, B; Long LongC; Long Longresult; for(inti =0; i < Gquerycount; i++) {GetChar (); scanf ("%c", &op); if(OP = ='C') {scanf ("%d%d%lld", &a, &b, &c); ADD (0, A-1, B-1, c); /*for (int k = 0; k < k++) {printf ("node[%d] ' sum =%lld, Inc =%lld\n", K, Gtreenode S[k].sum, Gtreenodes[k].inc); } */ } Else if(OP = ='Q') {scanf ("%d%d", &a, &b); Result= Querysum (0, A-1, B-1); printf ("%lld\n", result); } } return 0;}
poj3468-segment Tree