解:二维线段树用就行了,看了学长的代码学习了二维线段树,扣了好久的说。
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=810;
int num1[maxn][maxn],num[maxn<<2][maxn<<2],mxx[maxn<<2][maxn<<2],mnn[maxn<<2][maxn<<2];
int max1,min1,n,m;
void pushup(int nodex,int nodey){
mxx[nodex][nodey]=max(mxx[nodex][nodey<<1],mxx[nodex][nodey<<1|1]);
mnn[nodex][nodey]=min(mnn[nodex][nodey<<1],mnn[nodex][nodey<<1|1]);
}
void buildy(int l,int r,int x,int nodex,int nodey)//构建y方向的树
{
if(l==r){ //找到y树上确定的点
if(x!=-1)
mxx[nodex][nodey]=mnn[nodex][nodey]=num1[x][l];
else{
mxx[nodex][nodey]=max(mxx[nodex<<1][nodey],mxx[nodex<<1|1][nodey]);
mnn[nodex][nodey]=min(mnn[nodex<<1][nodey],mnn[nodex<<1|1][nodey]);
}
return ;
}
int mid=(l+r)/2;
buildy(l,mid,x,nodex,nodey<<1);
buildy(mid+1,r,x,nodex,nodey<<1|1);
pushup(nodex,nodey);
}
void buildx(int l,int r,int nodex)//开始构建x方向的树
{
if(l==r){ //找到确定的x树上的确定的点
buildy(1,n,l,nodex,1);//在x树中进行y树的构建
return ;
}
int mid=(l+r)/2;
buildx(l,mid,nodex<<1);
buildx(mid+1,r,nodex<<1|1);
buildy(1,n,-1,nodex,1);//关键的地方:看了好久...这个地方的作用是求整个矩阵的最大和最小值;一层层的求取的是以x树为分割的区域块的最大和最小值;
}
void updatey(int l,int r,int b,int x,int val,int nodex,int nodey)
{
if(l==r){
if(x!=-1)
mxx[nodex][nodey]=mnn[nodex][nodey]=val;
else
{
mxx[nodex][nodey]=max(mxx[nodex<<1][nodey],mxx[nodex<<1|1][nodey]);
mnn[nodex][nodey]=min(mnn[nodex<<1][nodey],mnn[nodex<<1|1][nodey]);
}
return ;
}
int mid = (l+r)/2;
if(b<=mid){
updatey(l,mid,b,x,val,nodex,nodey<<1);
}
else
updatey(mid+1,r,b,x,val,nodex,nodey<<1|1);
pushup(nodex,nodey);
}
void updatex(int l,int r,int x,int y,int val,int nodex)
{
if(l==r)
{
updatey(1,n,y,l,val,nodex,1);
return ;
}
int mid=(l+r)/2;
if(x<=mid)updatex(l,mid,x,y,val,nodex<<1);
else updatex(mid+1,r,x,y,val,nodex<<1|1);
updatey(1,n,y,-1,val,nodex,1);
}
void queryy(int l,int r,int b,int d,int nodex,int nodey)
{
if(b<=l&&r<=d)
{
max1=max(max1,mxx[nodex][nodey]);
min1=min(min1,mnn[nodex][nodey]);
return ;
}
int mid=(l+r)/2;
if(b<=mid)queryy(l,mid,b,d,nodex,nodey<<1);
if (d>mid)queryy(mid+1,r,b,d,nodex,nodey<<1|1);
}
void queryx(int a,int b,int c,int d,int l,int r,int nodex)
{
if(a<=l&&c>=r)
{
queryy(1,n,b,d,nodex,1);
return;
}
int mid=(l+r)/2;
if(a<=mid)
queryx(a,b,c,d,l,mid,nodex<<1);
if(c>mid)queryx(a,b,c,d,mid+1,r,nodex<<1|1);
}
int main()
{
int t;int count=0;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&num1[i][j]);
}
buildx(1,n,1);
int xl,xr,yl,yr ;
int a,b,c,d;
scanf("%d",&m);
printf("Case #%d:\n",++count);
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
max1=-INF,min1=INF;
d=(c+1)/2;xl=a-d+1;xr=a+d-1;//定义查询区域的边长范围
yl=b-d+1;yr=b+d-1;
if(xl<1)xl=1;
if(xr>n)xr=n;
if(yl<1)yl=1;
if(yr>n)yr=n;
//cout<<"kkkkk"<
再对x轴中的第x行进行线段树的构建,相当于是把矩阵先拆成一行一行,再分别对每一行进行一维线段树的构建,如此,查询和更新也就如是了*/