题目概述
给出一个n*n的矩阵,给出m个询问,每个询问形如x,y,z,表示询问以x,y为中心点的z*z子矩阵的最大值MAX和最小值MIN,输出floor((MIN+MAX)/2)并将x,y修改为floor((MIN+MAX)/2)(floor是向下取整)。
解题报告
这是经典的区域查询,单点修改。可以用线段树套线段树实现,只是要注意空间有点紧,储存线段树节点时不存左边界,右边界,而是临时计算,这样就可以减少空间开销。
示例程序
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=800,maxt=4*maxn,MAXINT=((1<<30)-1)*2+1;
int te,n,m,pic[maxn+5][maxn+5];
//===========================================================
struct SegmentTreexy //线段树套线段树
{
int MIN[maxt+5][maxt+5],MAX[maxt+5][maxt+5];
int posx,posy,Lx,Rx,Ly,Ry,fa,k;bool is_leaf; //fa是当前x树,is_leaf表示fa是否是叶节点
void Pushupy(int fa,int p) //更新列
{
MIN[fa][p]=min(MIN[fa][p<<1],MIN[fa][p<<1|1]);
MAX[fa][p]=max(MAX[fa][p<<1],MAX[fa][p<<1|1]);
}
void Pushupx(int fa,int p) //更新行
{
MIN[fa][p]=min(MIN[fa<<1][p],MIN[fa<<1|1][p]);
MAX[fa][p]=max(MAX[fa<<1][p],MAX[fa<<1|