Segment tree, Quad tree. All in O (log4n)
classNode//2D Segment Tree { Public: Node (Vector<vector<int>> &m,intIx0,intIy0,intIX1,intiy1): Sum (0), x0 (ix0), X1 (ix1), y0 (iy0), Y1 (iy1), UL (nullptr), Ur (nullptr), DL (nullptr), Dr (Nullptr) { if(ix0 > Ix1 | | iy0 > IY1)return; if(ix0 = = ix1 && Iy0 = =iy1) {Sum=m[iy0][ix0]; return; } intXmid =Getmidx (); intYmid =Getmidy (); UL=NewNode (M, ix0, Iy0, Xmid, Ymid); Sum+ = Ul->sum; if(Ix1 >xmid) {ur=NewNode (m, Xmid +1, Iy0, ix1, Ymid); Sum+ = Ur->sum; } if(Iy1 >Ymid) {DL=NewNode (M, ix0, Ymid +1, Xmid, iy1); Sum+ = Dl->sum; } if(Iy1 > Ymid && ix1 >xmid) {Dr=NewNode (m, Xmid +1, Ymid +1, ix1, iy1); Sum+ = Dr->sum; } } Long LongUpdateintRxintRyLong Longval) { if(Rx = = X0 && ry = = y0 && x0 = x1 && y0 = =y1) { Long LongD = Val-sum; Sum=Val; returnD; } intXmid =Getmidx (); intYmid =Getmidy (); Long LongD =0; if(Rx <= xmid && ry <=Ymid) {D= ul->Update (Rx, Ry, Val); } Else if(Rx > Xmid && ry <=Ymid) {D= ur->Update (Rx, Ry, Val); } Else if(Rx <= xmid && ry >Ymid) {D= dl->Update (Rx, Ry, Val); } Else if(Rx > Xmid && ry >Ymid) {D= dr->Update (Rx, Ry, Val); } Sum+=D; returnD; } Long Long Get(intRx0,intRy0,intRX1,intry1) { if(rx0 = = X0 && rx1 = = X1 && ry0 = y0 && Ry1 = =y1) { returnsum; } // intXmid =Getmidx (); intYmid =Getmidy (); Long LongD =0; if(rx0 <= xmid && ry0 <=Ymid) {D+ = Ul->Get(rx0, Ry0, Min (Xmid, rx1), Min (Ymid, ry1)); } if(Rx1 > Xmid && ry0 <=Ymid) {D+ = Ur->Get(Max (rx0, Xmid +1), Ry0, Rx1, Min (Ymid, ry1)); } if(rx0 <= xmid && ry1 >Ymid) {D+ = Dl->Get(Rx0, Max (Ymid +1, Ry0), Min (Rx1, xmid), ry1); } if(Rx1 > Xmid && ry1 >Ymid) {D+ = Dr->Get(Max (rx0, Xmid +1), Max (ry0, Ymid +1), RX1, ry1); } returnD; } Private: intGetmidx () {returnX0 + (x1-x0)/2; } intGetmidy () {returnY0 + (Y1-Y0)/2; } Private: //Mem VARs Long Longsum; intx0, X1; inty0, y1; Node*ul; Node*ur; Node*DL; Node*Dr; }; classNummatrix {Node*PSeg; Public: Nummatrix (Vector<vector<int>> &matrix) { inth =matrix.size (); if(!h)return; intW = matrix[0].size (); PSeg=NewNode (Matrix,0,0, W-1, H-1); } voidUpdateintRowintColintval) { if(pSeg) PSeg-Update (col, Row, Val); } intSumregion (intRow1,intCol1,intRow2,intcol2) { if(PSeg)returnPseg->Get(col1, Row1, col2, row2); return 0; } };
View Code
Leetcode "Range Sum Query 2d-mutable"