UVa 11297 Census 二维线段树模板

题目链接:https://vjudge.net/problem/UVA-11297

     二维线段树模板题,单点修改与区间查询,这里按照刘汝佳说的加了个build函数,能起到一定的优化效果。

#include
#include
#include
using namespace std;
const int INF = (1<<30);
const int maxn = 2000 + 10;
struct IntervalTree2D {
  int Max[maxn][maxn], Min[maxn][maxn], n, m;
  int xo, xleaf, x1, y1, x2, y2, x, y, v, vmax, vmin;

  void build1D(int o, int L, int R) {
    if(L == R) {
      if(xleaf) { scanf("%d", &v); Max[xo][o] = Min[xo][o] = v; return; }
      Max[xo][o] = max(Max[xo*2][o], Max[xo*2+1][o]);
      Min[xo][o] = min(Min[xo*2][o], Min[xo*2+1][o]);
    }
    else {
      int M = (L + R) >> 1;
      build1D(o*2, L, M);
      build1D(o*2+1, M+1, R);
      Max[xo][o] = max(Max[xo][o*2], Max[xo][o*2+1]);
      Min[xo][o] = min(Min[xo][o*2], Min[xo][o*2+1]);
    }
  }

  void build2D(int o, int L, int R) {
    if(L == R) {
      xleaf = 1;
      xo = o;
      build1D(1, 1, m);
    }
    else {
      int M = (L + R) >> 1;
      build2D(o*2, L, M);
      build2D(o*2+1, M+1, R);
      xleaf = 0; xo = o; build1D(1, 1, m);
    }
  }

  void query1D(int o, int L, int R) {
    if(y1 <= L && R <= y2) {
      vmax = max(vmax, Max[xo][o]);
      vmin = min(vmin, Min[xo][o]);
    }
    else {
      int M = (L + R) >> 1;
      if(y1 <= M) query1D(o*2, L, M);
      if(M < y2) query1D(o*2+1, M+1, R);
    }
  }

  void query2D(int o, int L, int R) {
    if(x1 <= L && R <= x2) {
      xo = o;
      query1D(1, 1, m);
    }
    else {
      int M = (L + R) >> 1;
      if(x1 <= M) query2D(o*2, L, M);
      if(M < x2) query2D(o*2+1, M+1, R);
    }
  }

  void modify1D(int o, int L, int R) {
    if(L == R) {
      if(xleaf) { Max[xo][o] = Min[xo][o] = v; return; }
      Max[xo][o] = max(Max[xo*2][o], Max[xo*2+1][o]);
      Min[xo][o] = min(Min[xo*2][o], Min[xo*2+1][o]);
    }
    else {
      int M = (L + R) >> 1;
      if(y <= M) modify1D(o*2, L, M);
      else modify1D(o*2+1, M+1, R);
      Max[xo][o] = max(Max[xo][o*2], Max[xo][o*2+1]);
      Min[xo][o] = min(Min[xo][o*2], Min[xo][o*2+1]);
    }
  }

  void modify2D(int o, int L, int R) {
     if(L == R) {
       xleaf = 1; xo = o; modify1D(1, 1, m);
     }
     else {
        int M = (L + R) >> 1;
        if(x <= M) modify2D(o*2, L, M);
        else modify2D(o*2+1, M+1, R);
        xo = o; xleaf = 0; modify1D(1, 1, m);
     }
  }

  void modify() { modify2D(1, 1, n); }
  void query() { vmax = -INF, vmin = INF; query2D(1, 1, n); }

};

IntervalTree2D t;

int main() {
  int n, m, Q, x1, y1, x2, y2, x, y, v;
  char op[10];
  scanf("%d", &n);
  m = n;
  t.n = n; t.m = n;
  t.build2D(1, 1, n);
  scanf("%d", &Q);
  while(Q--) {
    scanf("%s", op);
    if(op[0] == 'q') {
      scanf("%d%d%d%d", &t.x1, &t.y1, &t.x2, &t.y2);
      t.query();
      printf("%d %d\n", t.vmax, t.vmin);
    }
    else {
      scanf("%d%d%d", &t.x, &t.y, &t.v);
      t.modify();
    }
  }
  return 0;
}


你可能感兴趣的:(UVa,数据结构)