Given a matrix, query the maximum and minimum values of a sub-matrix, and then replace them with half (x, y) in this position, bare two-dimensional segment tree.
And one-dimensional almost, but is the one-dimensional preservation is the most value, and this is saved is a number of groups, and this array is a one-dimensional segment tree, so is a two-dimensional line segment tree. See code comments for details.
#include <cstdio>#include<cstring>#include<algorithm>using namespacestd;Const intMAXN = +;//there is a vertical y array on each x node, which is a columnstructNodey {intL, R; intMax, Min;};intLOCX[MAXN], LOCY[MAXN];//for the position of the given matrix (x, y) the corresponding x and Y positions in the segment tree are locx[x], locy[y];Const intINF =0x3f3f3f3f;intT, N;//size of the n matrixstructNodex {//The X-node is the normal one-dimensional segment tree intL, R; Nodey STY[MAXN<<2];//its node is not a normal value, but a one-dimensional array, which is actually a column voidBuildintRtintllintRr//for a column of achievements, as in one dimension, note that ll and l,ll are the interval left values in the column, and L is the interval lvalue in the business.{STY[RT].L=ll; STY[RT].R=RR; STY[RT]. Min=inf; STY[RT]. Max= -inf; if(LL = =RR) {Locy[ll]= RT;//location return; } intMID = (ll + RR)/2; Build (Rt<<1, LL, mid); Build (Rt<<1|1, Mid +1, RR); } intQuerymin (intRtintllintRr//The maximum value of the LL-RR interval in the query column { if(STY[RT].L = = ll && STY[RT].R = =RR)returnSty[rt]. Min; intMid = (STY[RT].L + STY[RT].R)/2; if(RR <= mid)returnQuerymin (Rt <<1, LL, RR); Else if(ll > Mid)returnQuerymin (Rt <<1|1, LL, RR); returnMIN (Querymin (RT <<1, LL, mid), Querymin (Rt <<1|1, Mid +1, RR)); } intQuerymax (intRtintllintRR) { if(STY[RT].L = = ll && STY[RT].R = =RR)returnSty[rt]. Max; intMid = (STY[RT].L + STY[RT].R)/2; if(RR <= mid)returnQuerymax (Rt <<1, LL, RR); Else if(ll > Mid)returnQuerymax (Rt <<1|1, LL, RR); returnMax (Querymax (Rt <<1, LL, mid), Querymax (Rt <<1|1, Mid +1, RR)); }}STX[MAXN<<2];voidBuildintRtintLintR//Achievements{STX[RT].L=l; STX[RT].R=R; Stx[rt].build (1,1, N); if(L = =R) {Locx[l]=RT; return; } intMid = (L + r)/2; Build (Rt<<1, L, mid); Build (Rt<<1|1, Mid +1, R);}voidModifyintXintYintVal//change (x, y) The value of this point{ inttx =Locx[x]; intTy =Locy[y]; Stx[tx].sty[ty]. Min= Stx[tx].sty[ty]. Max =Val; for(inti = TX; I I >>=1)//Update pushup up for(intj = ty; J J >>=1) { if(i = = TX && J = = ty)Continue; if(J = =ty) {Stx[i].sty[j]. Min= Min (stx[i<<1].STY[J]. Min, stx[i<<1|1].sty[j]. Min); STX[I].STY[J]. Max= Max (stx[i<<1].STY[J]. Max, stx[i<<1|1].sty[j]. MAX); } Else{stx[i].sty[j]. Min= Min (stx[i].sty[j<<1]. Min, stx[i].sty[j<<1|1]. Min); STX[I].STY[J]. Max= Max (stx[i].sty[j<<1]. Max, stx[i].sty[j<<1|1]. MAX); } }}intQuerymin (intRtintX1,intX2,intY1,inty2)//Query in Matrix behavior (x1 to x2), listed as the maximum value (y1 to y2){ if(STX[RT].L = = X1 && STX[RT].R = =x2)returnStx[rt].querymin (1, y1, y2); intMid = (STX[RT].L + STX[RT].R)/2; if(X2 <= mid)returnQuerymin (Rt <<1, x1, x2, y1, y2); Else if(X1 > Mid)returnQuerymin (Rt <<1|1, x1, x2, y1, y2); returnMIN (Querymin (RT <<1, X1, Mid, Y1, y2), Querymin (Rt <<1|1, Mid +1, x2, y1, y2));}intQuerymax (intRtintX1,intX2,intY1,inty2) { if(STX[RT].L = = X1 && STX[RT].R = =x2)returnStx[rt].querymax (1, y1, y2); intMid = (STX[RT].L + STX[RT].R)/2; if(X2 <= mid)returnQuerymax (Rt <<1, x1, x2, y1, y2); Else if(X1 > Mid)returnQuerymax (Rt <<1|1, x1, x2, y1, y2); returnMax (Querymax (Rt <<1, X1, Mid, Y1, y2), Querymax (Rt <<1|1, Mid +1, x2, y1, y2));}intMain () {scanf ("%d", &T); intKase =0; while(t--) {scanf ("%d", &N); Build (1,1, n);//Achievements intMat; printf ("Case #%d:\n", ++Kase); for(inti =1; I <= N; i++) for(intj =1; J <= N; J + +) {scanf ("%d", &mat); Modify (I, J, Mat);//Update } intQ; scanf ("%d", &P); while(q--) { intx, y, Len; scanf (" %d%d%d", &x, &y, &Len); Len/=2; intX1 = Max (X-len,1); intx2 = min (x +Len, N); inty1 = max (Y-len,1); inty2 = min (y +Len, N); intMax = Querymax (1, x1, x2, y1, y2); intMin = Querymin (1, x1, x2, y1, y2); intAns = (Min + Max)/2; printf ("%d\n", ans); Modify (x, y, ans); } } return 0;}
HDU 4819 Mosaic (two-dimensional line segment tree)