hdu4819 二维线段树:点修改区间查询

这是一道裸的二维线段树区间查询最大最小值+点修改,学习啦!

二维线段树其实就是在一维线段树的每一个节点上增加一个一维线段树

具体从x节点传到y节点还要看是区间还是节点,大部分操作都和一维线段树差不多

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 using namespace std;
  5 int maxv[4*801][4*801],minv[4*801][4*801];
  6 int a[802][802],fmax,fmin,n;
  7 void build_y(int ox,int o,int l,int r,int x,int kind)
  8 {
  9   int mid=l+(r-l)/2;
 10   if (l==r){
 11     if (kind) maxv[ox][o]=minv[ox][o]=a[x][l];
 12     else{
 13       maxv[ox][o]=max(maxv[ox*2][o],maxv[ox*2+1][o]);
 14       minv[ox][o]=min(minv[ox*2][o],minv[ox*2+1][o]);
 15     }
 16     return;
 17   }
 18   build_y(ox,o*2,l,mid,x,kind);
 19   build_y(ox,o*2+1,mid+1,r,x,kind);
 20   maxv[ox][o]=max(maxv[ox][o*2],maxv[ox][o*2+1]);
 21   minv[ox][o]=min(minv[ox][o*2],minv[ox][o*2+1]);
 22 }
 23 void build_x(int o,int l,int r)
 24 {
 25   int mid=l+(r-l)/2;
 26   if (l==r) build_y(o,1,1,n,l,1);
 27   else{
 28     build_x(o*2,l,mid);
 29     build_x(o*2+1,mid+1,r);
 30     build_y(o,1,1,n,0,0);
 31   }
 32 }
 33 void update_y(int ox,int o,int l,int r,int qy,int num,int kind)
 34 {
 35   int mid=l+(r-l)/2;
 36   if (l==r) {
 37     if (kind) maxv[ox][o]=minv[ox][o]=num;
 38     else{
 39       maxv[ox][o]=max(maxv[ox*2][o],maxv[ox*2+1][o]);
 40       minv[ox][o]=min(minv[ox*2][o],minv[ox*2+1][o]);
 41     }
 42     return;
 43   }
 44   if (qy<=mid) update_y(ox,o*2,l,mid,qy,num,kind);
 45   else update_y(ox,o*2+1,mid+1,r,qy,num,kind);
 46   maxv[ox][o]=max(maxv[ox][o*2],maxv[ox][o*2+1]);
 47   minv[ox][o]=min(minv[ox][o*2],minv[ox][o*2+1]);
 48 }
 49 void update_x(int o,int l,int r,int qx,int qy,int num)
 50 {
 51   int mid=l+(r-l)/2;
 52   if (l==r) update_y(o,1,1,n,qy,num,1);
 53   else{
 54     if (qx<=mid) update_x(o*2,l,mid,qx,qy,num);
 55     else update_x(o*2+1,mid+1,r,qx,qy,num);
 56     update_y(o,1,1,n,qy,num,0);
 57   }
 58 }
 59 void query_y(int ox,int o,int l,int r,int y1,int y2)
 60 {
 61   int mid=l+(r-l)/2;
 62   if (y1<=l&&y2>=r){
 63     fmax=max(fmax,maxv[ox][o]);
 64     fmin=min(fmin,minv[ox][o]);
 65     return;
 66   }
 67   if (y1<=mid) query_y(ox,o*2,l,mid,y1,y2);
 68   if (y2>mid) query_y(ox,o*2+1,mid+1,r,y1,y2);
 69 }
 70 void query_x(int o,int l,int r,int x1,int x2,int y1,int y2)
 71 {
 72   int mid=l+(r-l)/2;
 73   if (x1<=l&&x2>=r) query_y(o,1,1,n,y1,y2);
 74   else{
 75     if (x1<=mid) query_x(o*2,l,mid,x1,x2,y1,y2);
 76     if (x2>mid) query_x(o*2+1,mid+1,r,x1,x2,y1,y2);
 77   }
 78 }
 79 int main()
 80 {
 81   int T,t,x,y,l,i,j,m;
 82   scanf("%d",&T);
 83   for (t=1;t<=T;t++)
 84   {
 85     scanf("%d",&n);
 86     for (i=1;i<=n;i++)
 87       for (j=1;j<=n;j++) scanf("%d",&a[i][j]);
 88     build_x(1,1,n);
 89     printf("Case #%d:\n",t);
 90     scanf("%d",&m);
 91     while (m--)
 92     {
 93       scanf("%d%d%d",&x,&y,&l);
 94       l=(l-1)/2; fmax=0; fmin=0x3f3f3f3f;
 95       query_x(1,1,n,max(x-l,1),min(x+l,n),max(y-l,1),min(y+l,n));
 96       printf("%d\n",(fmax+fmin)/2);
 97       update_x(1,1,n,x,y,(fmax+fmin)/2);
 98     }
 99   }
100   return 0;
101 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819

 

posted on 2015-02-09 01:04  xiao_xin  阅读(261)  评论(0编辑  收藏  举报

导航