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

 

转载于:https://www.cnblogs.com/xiao-xin/articles/4280757.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值