hdu4819 二维线段树

来源:互联网 发布:淘宝小铺名称能改吗 编辑:程序博客网 时间:2024/06/07 23:55

题意:维护矩阵中的值 使得其中的值可以被修改 然后维护最大值和最小值


做法:对于给定的矩阵进行暴力建树(没有写build 不过写了也应该是n^2)然后就是维护的过程了 

写了这一题以后才算是了解了二维线段树的结构 然后有一个地方写错了 一直没有调试出来

就是当更新的不是第一维度的叶子并且是第二维度的叶子的时候 其实它的值是来自于第一维度的左右儿子

这样就可以做到把信息从底层递归上来了

#include<cstdio>#include<iostream>#include<limits.h>using namespace std;#define maxn 888#define ls (rt<<1)#define rs (rt<<1|1)#define mid ((l+r)>>1)#define lls (rrt<<1)#define rrs (rrt<<1|1)#define mmid ((ll+rr)>>1)#define inf INT_MAXint mi[maxn<<2][maxn<<2],ma[maxn<<2][maxn<<2];int amin,amax,n;void ins(int rt,int l,int r,int x,int rrt,int ll,int rr,int y,int w){    if(l==r){        if(ll==rr){            if(l!=-1){  //leaf                mi[rt][rrt]=ma[rt][rrt]=w;            }else{                mi[rt][rrt]=min(mi[ls][rrt],mi[rs][rrt]);                ma[rt][rrt]=max(ma[ls][rrt],ma[rs][rrt]);            }            return ;        }        if(y<=mmid)ins(rt,l,r,x,lls,ll,mmid,y,w);        if(mmid<y)ins(rt,l,r,x,rrs,mmid+1,rr,y,w);        ma[rt][rrt]=max(ma[rt][lls],ma[rt][rrs]);        mi[rt][rrt]=min(mi[rt][lls],mi[rt][rrs]);        return ;    }else{        if(x<=mid)ins(ls,l,mid,x,rrt,ll,rr,y,w);        if(mid<x)ins(rs,mid+1,r,x,rrt,ll,rr,y,w);        ins(rt,-1,-1,x,rrt,1,n,y,w);    }}void query(int rt,int l,int r,int L,int R,int rrt,int ll,int rr,int LL,int RR){    if(L<=l&&r<=R){        if(LL<=ll&&rr<=RR){            amax=max(amax,ma[rt][rrt]);            amin=min(amin,mi[rt][rrt]);            return ;        }        if(LL<=mmid)query(rt,l,r,L,R,lls,ll,mmid,LL,RR);        if(mmid<RR)query(rt,l,r,L,R,rrs,mmid+1,rr,LL,RR);    }else{        if(L<=mid)query(ls,l,mid,L,R,rrt,ll,rr,LL,RR);        if(mid<R)query(rs,mid+1,r,L,R,rrt,ll,rr,LL,RR);    }}int x,xi,yi,l;int xl,xr,yl,yr;int main(){    int _,x;scanf("%d",&_);    for(int z=1;z<=_;++z){        scanf("%d",&n);                for(int i=1;i<=(804<<2);++i)            for(int j=1;j<=(804<<2);++j)                ma[i][j]=-inf,mi[i][j]=inf;                for(int i=1;i<=n;++i){            for(int j=1;j<=n;++j){                scanf("%d",&x);                ins(1,1,n,i,1,1,n,j,x);            }        }        printf("Case #%d:\n",z);        scanf("%d",&x);        while(x--){            scanf("%d%d%d",&xi,&yi,&l);            amax=-inf;amin=inf;            xl=max(1,xi-l/2);            xr=min(n,xi+l/2);            yl=max(1,yi-l/2);            yr=min(n,yi+l/2);            query(1,1,n,xl,xr,1,1,n,yl,yr);            printf("%d\n",(amax+amin)/2);            ins(1,1,n,xi,1,1,n,yi,(amax+amin)/2);        }    }    return 0;}


0 0