题意:
给定一个N*N的矩阵,每个格子都有一个数,再给出Q个询问,每次询问以(x,y)为中心的边长为L的正方形矩阵中的最大值和最小值,并修改(x,y)的值为(MAX+MIN)/2
分析:
1)四叉树
对于查询矩阵的最值+修改问题,考虑二维线段树,参照一维线段树的写法:每次将区间二分成两个子区间,对应矩阵应对X,Y同时二分,也就是4个子矩阵,即左上、右上、左下,右下四部分,所以要建一颗四叉树,如果当前矩阵为一维时,只需二分成两个子区间,如下图所示:
归纳总结得出节点X的儿子节点为:X*4-2+a(0=<a<=3,根节点为1),其他就和一维线段树一样了
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3+13;
int n,m,x,y,L,T,q,a[maxn][maxn];
struct tree{
int x1,y1,x2,y2;
int MAX,MIN;
}tr[maxn*maxn*4];
inline int son(int p,int x){
return p*4-2+x;
}
void pushup1(int x){ //四叉树的pushup
tr[x].MAX = max(tr[son(x,0)].MAX,tr[son(x,1)].MAX);
tr[x].MIN = min(tr[son(x,0)].MIN,tr[son(x,1)].MIN);
for(int i = 2;i < 4; ++i){
tr[x].MAX = max(tr[x].MAX,tr[son(x,i)].MAX);
tr[x].MIN = min(tr[x].MIN,tr[son(x,i)].MIN);
}
}
void pushup2(int x){ //二叉树的pushup
tr[x].MAX = max(tr[son(x,0)].MAX,tr[son(x,1)].MAX);
tr[x].MIN = min(tr[son(x,0)].MIN,tr[son(x,1)].MIN);
}
void buil