Two-dimensional line tree template problem, and one-dimensional thinking, update the time to pay attention to the details.
Save Template:
/* Two-dimensional line tree template finishing */#include <cstdio> #include <algorithm>using namespace std; #define Lson (pos<<1) #define Rson (pos<<1|1) const int MAXN = 805;const int INF = (1 <<); int n;int posx[maxn],posy[maxn];//positioned Array (Quick Find update interval , upward recursion)//y direction segment tree interval node struct ny{int l,r; int minv,maxv;};/ /x Direction segment tree interval node struct nx{Ny nodey[maxn << 2]; int l,r; void build (int l,int r,int pos) {nodey[pos].l = l; NODEY[POS].R = R; NODEY[POS].MINV = INF; NODEY[POS].MAXV =-inf; if (L = = r) {Posy[l] = pos; Return } int mid = (L + r) >> 1; Build (L,mid,lson); Build (mid + 1,r,rson); } int Querymax (int l,int r,int POS) {//l R is the interval that needs to be queried if (L <= nodey[pos].l && nodey[pos].r <= R) return NODEY[POS].MAXV; int mid = (nodey[pos].l + nodey[pos].r) >> 1; int ret =-INF; if (L <= mid) ret = max (Ret,querymax (L,r,lson)); if (R > mid) ret = max (Ret,querymax (L,r,rson)); return ret; } int querymin (int l,int r,int POS) {//l R is the interval that needs to be queried if (L <= nodey[pos].l && nodey[pos].r <= R) return NODEY[POS].MINV; int mid = (nodey[pos].l + nodey[pos].r) >> 1; int ret = INF; if (L <= mid) ret = min (ret,querymin (L,r,lson)); if (R > Mid) ret = min (ret,querymin (L,r,rson)); return ret; }}NODEX[MAXN << 2];void Build (int l,int r,int pos) {nodex[pos].l = l; NODEX[POS].R = R; Nodex[pos].build (1,n,1); if (L = = r) {Posx[l] = pos; Return } int mid = (L + r) >> 1; Build (L,mid,lson); Build (mid + 1,r,rson);} int Querymax (int x1,int x2,int y1,int y2,int pos) {if (x1 <= nodex[pos].l && nodex[pos].r <= x2) {R Eturn Nodex[pos].querymax (y1,y2,1); } int mid = (nodex[pos].l + nodex[pos].r) >> 1; int ret =-inf; if (X1 <= mid) ret = max (Ret,querymax (X1,x2,y1,y2,lson)); if (X2 > Mid) ret = max (Ret,querymax (X1,x2,y1,y2,rson)); return ret;} int querymin (int x1,int x2,int y1,int y2,int pos) {if (x1 <= nodex[pos].l && nodex[pos].r <= x2) {R Eturn nodex[pos].querymin (y1,y2,1); } int mid = (nodex[pos].l + nodex[pos].r) >> 1; int ret = INF; if (X1 <= mid) ret = min (ret,querymin (X1,x2,y1,y2,lson)); if (X2 > Mid) ret = min (ret,querymin (X1,x2,y1,y2,rson)); return ret;} /* About update here is a difficult point, according to the positioning of the array found to update the node when updating the first round of the x-coordinate segment tree, followed by several rounds of update y-coordinate segment Tree */void update (int x,int y,int value) {int _x = PO sx[x],_y = Posy[y]; First update the horizontal axis NODEX[_X].NODEY[_Y].MINV = NODEX[_X].NODEY[_Y].MAXV = value; for (int i = _x; I >= 1; I >>= 1) {if (i! = _x) {nodex[i].nodey[_y].minv = min (nodex[i << 1].nodey[_y].minv,nodex[i << 1|1].NODEY[_Y].MINV); NODEX[I].NODEY[_Y].MAXV = max (Nodex[i << 1].nodey[_y].maxv,nodex[i << 1|1].NODEY[_Y].MAXV); }}//update ordinate segment tree for (int i = _x, I >= 1; I >>= 1) {for (int j = _y; J >= 1; J >>= 1) { if (j = = _y) continue; NODEX[I].NODEY[J].MINV = min (nodex[i].nodey[j << 1].minv,nodex[i].nodey[j << 1|1].MINV); NODEX[I].NODEY[J].MAXV = max (nodex[i].nodey[j << 1].maxv,nodex[i].nodey[j << 1|1].maxv); }}}int Main () {int t,case = 1; scanf ("%d", &t); while (t--) {scanf ("%d", &n); Build (1,n,1); int value; for (int i = 1; I <= n; i++) for (int j = 1; J <= N; j + +) {scanf ("%d", &value); Update (I,j,value); } int m,x,y,l; scanf ("%d", &m); printf ("Case #%d:\n", case++); while (m--) {scanf ("%d%d%d", &x,&y,&l); int x1 = x-l/2; if (X1 < 1) x1 = 1; int x2 = x + l/2; if (x2 > N) x2 = n; int y1 = y-l/2; if (Y1 < 1) y1 = 1; int y2 = y + l/2; if (y2 > N) y2 = n; int MAXV = Querymax (x1,x2,y1,y2,1); int MINV = Querymin (x1,x2,y1,y2,1); int aver = (MAXV + MINV)/2; printf ("%d\n", aver); Update (X,y,aver); }} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
"HDU 4819" Mosaic Two-dimensional line segment tree template