hdu4819 Mosaic
13年长春regional。二维线段树。
需要变更某个点,询问某个矩形的最大最小值。
在二维线段树里这只算个裸题。
这里只说一点,为了保持O(nlogn)的复杂度查询,在更新点的时候,需要将所有包含该点的区间的最大最小值都变更。
假设n=3,当你修改点(x=2,y=3)你不仅要修改x=[2,2]的y轴线段树,也要修改x=[1,2]对应的y轴线段树。
这里有个很巧妙的方法,其实我之前没做过这种题,当时YY出来的。看起来别人也是这么写。
就是在更新x=[1,2]的y轴线段树的y=3的点,设为ty[x][p],只要对ty[x<<1][p],ty[x<<1|1][p]取最大最小就可以了,含义很直观,就是对x=[1,1],x=[2,2]两颗树的对应节点取最大最小。
13年长春regional。二维线段树。
需要变更某个点,询问某个矩形的最大最小值。
在二维线段树里这只算个裸题。
这里只说一点,为了保持O(nlogn)的复杂度查询,在更新点的时候,需要将所有包含该点的区间的最大最小值都变更。
假设n=3,当你修改点(x=2,y=3)你不仅要修改x=[2,2]的y轴线段树,也要修改x=[1,2]对应的y轴线段树。
这里有个很巧妙的方法,其实我之前没做过这种题,当时YY出来的。看起来别人也是这么写。
就是在更新x=[1,2]的y轴线段树的y=3的点,设为ty[x][p],只要对ty[x<<1][p],ty[x<<1|1][p]取最大最小就可以了,含义很直观,就是对x=[1,1],x=[2,2]两颗树的对应节点取最大最小。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define ls (p<<1)
#define rs (p<<1|1)
#define Maxn 805
struct segtreex{
short l,r;
}tx[Maxn*3];
struct segtreey{
short l,r;
int mi,ma;
}ty[Maxn*3][Maxn*3];
int n;
int a[Maxn][Maxn];
void buildy(int l,int r,int p,int x,int xpos){
ty[x][p].l=l;ty[x][p].r=r;
if (l==r) {
if (xpos) ty[x][p].ma=ty[x][p].mi=a[xpos][l];
else {
ty[x][p].ma=max(ty[x<<1][p].ma,ty[x<<1|1][p].ma);
ty[x][p].mi=min(ty[x<<1][p].mi,ty[x<<1|1][p].mi);
}
return;
}
int m=l+r>>1;
buildy(l,m,ls,x,xpos);
buildy(m+1,r,rs,x,xpos);
ty[x][p].ma=max(ty[x][ls].ma,ty[x][rs].ma);
ty[x][p].mi=min(ty[x][ls].mi,ty[x][rs].mi);
}
void buildx(int l,int r,int p){
tx[p].l=l;tx[p].r=r;
if (l==r) {buildy(1,n,1,p,l);return;}
int m=l+r>>1;
buildx(l,m,ls);
buildx(m+1,r,rs);
buildy(1,n,1,p,0);
}
void updatey(int pos,int p,int x,int val,int xpos){
if (ty[x][p].l==ty[x][p].r){
if (xpos) ty[x][p].ma=ty[x][p].mi=val;
else {
ty[x][p].ma=max(ty[x<<1][p].ma,ty[x<<1|1][p].ma);
ty[x][p].mi=min(ty[x<<1][p].mi,ty[x<<1|1][p].mi);
}
return;
}
int m=ty[x][p].l+ty[x][p].r>>1;
if (pos<=m) updatey(pos,ls,x,val,xpos);
else updatey(pos,rs,x,val,xpos);
ty[x][p].ma=max(ty[x][ls].ma,ty[x][rs].ma);
ty[x][p].mi=min(ty[x][ls].mi,ty[x][rs].mi);
}
void updatex(int pos,int p,int y,int val){
if (tx[p].l==tx[p].r){
updatey(y,1,p,val,pos);
return;
}
int m=tx[p].l+tx[p].r>>1;
if (pos<=m) updatex(pos,ls,y,val);
else updatex(pos,rs,y,val);
updatey(y,1,p,val,0);
}
int queryy(int l,int r,int p,int x,int func){
if (ty[x][p].l==l&&r==ty[x][p].r) {
if (func==0) return ty[x][p].ma;
else return ty[x][p].mi;
}
int m=ty[x][p].l+ty[x][p].r>>1;
if (r<=m) return queryy(l,r,ls,x,func);
else if (l>m) return queryy(l,r,rs,x,func);
else {
if (func==0) return max(queryy(l,m,ls,x,func),queryy(m+1,r,rs,x,func));
else return min(queryy(l,m,ls,x,func),queryy(m+1,r,rs,x,func));
}
}
int queryx(int l,int r,int p,int yl,int yr,int func){
if (tx[p].l==l&&r==tx[p].r) {
return queryy(yl,yr,1,p,func);
}
int m=tx[p].l+tx[p].r>>1;
if (r<=m) return queryx(l,r,ls,yl,yr,func);
else if (l>m) return queryx(l,r,rs,yl,yr,func);
else{
if (func==0) return max(queryx(l,m,ls,yl,yr,func),queryx(m+1,r,rs,yl,yr,func));
else return min(queryx(l,m,ls,yl,yr,func),queryx(m+1,r,rs,yl,yr,func));
}
}
int main(){
//freopen("gin.txt","r",stdin);
int tcas,cas,i,j,q,x,y,l,len,x1,y1,x2,y2,tmp,ma,mi;
scanf("%d",&tcas);
for(cas=1;cas<=tcas;++cas){
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=1;j<=n;++j){
scanf("%d",&a[i][j]);
}
}
buildx(1,n,1);
scanf("%d",&q);
printf("Case #%d:\n",cas);
for(i=1;i<=q;++i){
scanf("%d%d%d",&x,&y,&l);
len=l/2;
x1=max(x-len,1);
y1=max(y-len,1);
x2=min(x+len,n);
y2=min(y+len,n);
ma=queryx(x1,x2,1,y1,y2,0);
mi=queryx(x1,x2,1,y1,y2,1);
tmp=(ma+mi)/2;
printf("%d\n",tmp);
updatex(x,1,y,tmp);
}
}
return 0;
}