题目链接:UVA-11297-Census
题意是给定n*n(n<=500)大小的矩阵,询问操作是询问一个矩形内的最值,修改操作是修改某个点的值。
因此可以用二维线段树搞。
二维线段树就是线段树套线段树,x方向建立一棵线段树,其每一结点是一棵在y方向的线段树。
查询:先沿x方向查询,当该区间在查询区间内,沿y方向查询。
修改:沿x方向修改,如果这个点是x方向的叶子结点,那么在y 方向查找到叶子结点时,直接赋值即可。否则当在y方向查找到叶子结点时,要通过其在x方向的叶子结点获得在y方向叶子结点的值,详情看 push_up_2D
和 push_up_1D
的使用位置。
#include<bits/stdc++.h>
using namespace std;
const int maxn=507;
const int INF=1e9+7;
int n;
int Mat[maxn][maxn];
struct IntervalTree2D
{
int Max[maxn<<2][maxn<<2],Min[maxn<<2][maxn<<2];
int xl,xr,yl,yr,rt1,maxv,minv,x,y,v,leaf;
inline void push_up_2D(int rt)
{
Max[rt1][rt]=max(Max[rt1<<1][rt],Max[rt1<<1|1][rt]);
Min[rt1][rt]=min(Min[rt1<<1][rt],Min[rt1<<1|1][rt]);
}
inline void push_up_1D(