顾名思义,二维线段树就是在一棵线段树的每一个节点,都保存着另一棵线段树的根节点编号。
二维线段树通常支持以下2种功能:
1、单点修改;
2、二维区间查询。
为了实现这两种功能,我们需要建一棵外层线段树(可以动态开点也可以静态开点),对于外层线段树的每一个节点,我们都保存一个内层线段树的根节点编号(内层线段树必须动态开点,否则MLE)。
代码:
#define sz 100000
struct hh
{
long long lson,rson,rt;//左儿子,右儿子,内层线段树根节点编号
}out[sz<<1];//外层线段树
struct hhh
{
long long lson,rson,v;//左儿子,右儿子,值
}in[sz<<7];//内层线段树
在单点修改时,要在外层线段树查询点的一维,并沿途修改内层线段树。内层线段树查询点的另一维,找到后修改并回溯。
代码:
#define sz 100000
void modify_in(int &k,int l,int r,int y,int v)//内层修改
{
if (!k) k=++cnt2;//动态开点
in[k].v=max(in[k].v,v);//更新节点值
if (l==r) return;//修改完毕
int mid=(l+r)>>1;
if (y<=mid) modify_in(in[k].lson,l,mid,y,v);
else modify_in(in[k].rson,mid+1,r,y,v);
}
void m