数据结构:二维线段树

顾名思义,二维线段树就是在一棵线段树的每一个节点,都保存着另一棵线段树的根节点编号。

二维线段树通常支持以下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 modify_out(int &k,int l,int r,int x,int y,int v)//外层修改 
{
    if (!k) k=++cnt1;//动态开点 
    modify_in(out[k].rt,1,sz,y,v);//沿途修改 
    if (l==r) return;//修改完毕 
    int mid=(l+r)>>1;
    if (x<=mid) modify_out(out[k].lson,l,mid,x,y,v);
    else modify_out(out[k].rson,mid+1,r,x,y,v);
}

二维区间查询时,与普通线段树很像,但要在锁定一维后在内层线段树查找另一维,然后才能得出答案。

代码:

#define sz 100000 
int query_in(int k,int l,int r,int y1,int y2)//内层查询 
{
    if (!k) return 0;//没有这个点 
    if (y1<=l&&r<=y2) return in[k].v;//第二维包含,返回值 
    int mid=(l+r)>>1,ret=0;
    if (y1<=mid) ret=max(ret,query_in(in[k].lson,l,mid,y1,y2));
    if (y2>mid) ret=max(ret,query_in(in[k].rson,mid+1,r,y1,y2));
	return ret; 
}
int query_out(int k,int l,int r,int x1,int x2,int y1,int y2)
{
    if (!k) return 0;//没有这个点 
    if (x1<=l&&r<=x2) return query_in(out[k].rt,1,sz,y1,y2);//第一维包含,查询第二维 
    int mid=(l+r)>>1,ret=0;
    if (x1<=mid) ret=max(ret,query_out(out[k].lson,l,mid,x1,x2,y1,y2));
    if (x2>mid) ret=max(ret,query_out(out[k].rson,mid+1,r,x1,x2,y1,y2));
    return ret;
}

这便是二维线段树的全部实现方法。

实战:

1、POJ2029 Get Many Persimmon Trees http://poj.org/problem?id=2029

2、POJ1195 Mobile phones http://poj.org/problem?id=1195

3、洛谷4093 序列 https://www.luogu.org/problemnew/show/P4093 

(洛谷4093:我的另一篇博客内给出了题解http://blog.csdn.net/pb122401/article/details/79310796)

    原文作者:B树
    原文地址: https://blog.csdn.net/pb122401/article/details/79325126
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞