点击打开链接
二维线段树模板题 二维与一维线段树都是一个道理 即把大的区域或区间分成更小的部分 难在理解二维中大区域和小区域之间的关系
可以当作树套树来想 二维中每个小区间都代表一棵一维线段树 确定二维中每一个小区间就是确定了一个区域有哪些行 再确定对应一维线段树中某个区间 就是确定了一个区域有哪些列
#include
#include
#include
using namespace std;
#define N 0x3f3f3f3f
int minn[4010][4010],maxx[4010][4010];
int n,minnn,maxxx;
void pushupy(int curx,int cury)
{
minn[curx][cury]=min(minn[curx][cury*2],minn[curx][cury*2+1]);
maxx[curx][cury]=max(maxx[curx][cury*2],maxx[curx][cury*2+1]);
return;
}
void pushupxI(int l,int r,int curx,int cury)
{
int m;
minn[curx][cury]=min(minn[curx*2][cury],minn[curx*2+1][cury]);
maxx[curx][cury]=max(maxx[curx*2][cury],maxx[curx*2+1][cury]);
if(l==r) return;
m=(l+r)/2;
pushupxI(l,m,curx,cury*2);
pushupxI(m+1,r,curx,cury*2+1);
return;
}
void pushupxII(int tary,int l,int r,int curx,int cury)
{
int m;
minn[curx][cury]=min(minn[curx*2][cury],minn[curx*2+1][cury]);
maxx[curx][cury]=max(maxx[curx*2][cury],maxx[curx*2+1][cury]);
if(l==r) return;
m=(l+r)/2;
if(tary<=m) pushupxII(tary,l,m,curx,cury*2);
else pushupxII(tary,m+1,r,curx,cury*2+1);
return;
}
void buildy(int l,int r,int curx,int cury)
{
int m,t;
if(l==r)
{
scanf("%d",&t);
minn[curx][cury]=t;
maxx[curx][cury]=t;
return;
}
m=(l+r)/2;
buildy(l,m,curx,cury*2);
buildy(m+1,r,curx,cury*2+1);
pushupy(curx,cury);
return;
}
void buildx(int l,int r,int curx)
{
int m;
if(l==r)
{
buildy(1,n,curx,1);
return;
}
m=(l+r)/2;
buildx(l,m,curx*2);
buildx(m+1,r,curx*2+1);
pushupxI(1,n,curx,1);
return;
}
void queryy(int yl,int yr,int l,int r,int curx,int cury)
{
int m;
if(yl<=l&&r<=yr)
{
minnn=min(minnn,minn[curx][cury]);
maxxx=max(maxxx,maxx[curx][cury]);
return;
}
m=(l+r)/2;
if(yl<=m) queryy(yl,yr,l,m,curx,cury*2);
if(yr>=m+1) queryy(yl,yr,m+1,r,curx,cury*2+1);
return;
}
void queryx(int xl,int xr,int yl,int yr,int l,int r,int curx)
{
int m,res;
if(xl<=l&&r<=xr)
{
queryy(yl,yr,1,n,curx,1);
return;
}
m=(l+r)/2;
if(xl<=m) queryx(xl,xr,yl,yr,l,m,curx*2);
if(xr>=m+1) queryx(xl,xr,yl,yr,m+1,r,curx*2+1);
return;
}
void updatey(int tary,int val,int l,int r,int curx,int cury)
{
int m;
if(l==r)
{
minn[curx][cury]=val;
maxx[curx][cury]=val;
return;
}
m=(l+r)/2;
if(tary<=m) updatey(tary,val,l,m,curx,cury*2);
else updatey(tary,val,m+1,r,curx,cury*2+1);
pushupy(curx,cury);
return;
}
void updatex(int tarx,int tary,int val,int l,int r,int curx)
{
int m;
if(l==r)
{
updatey(tary,val,1,n,curx,1);
return;
}
m=(l+r)/2;
if(tarx<=m) updatex(tarx,tary,val,l,m,curx*2);
else updatex(tarx,tary,val,m+1,r,curx*2+1);
pushupxII(tary,1,n,curx,1);
return;
}
int main()
{
int t,cas,i,j,q,x,y,l,val;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d",&n);
for(i=1;i<=4*n;i++)
{
for(j=1;j<=4*n;j++)
{
minn[i][j]=N;
maxx[i][j]=-N;
}
}
buildx(1,n,1);
scanf("%d",&q);
printf("Case #%d:\n",cas);
while(q--)
{
scanf("%d%d%d",&x,&y,&l);
minnn=N,maxxx=-N;
queryx(max(1,x-l/2),min(n,x+l/2),max(1,y-l/2),min(n,y+l/2),1,n,1);
val=(minnn+maxxx)/2;
updatex(x,y,val,1,n,1);
printf("%d\n",val);
}
}
return 0;
}