树套树(模板?)

代码用于解决二维待修改RMQ问题
UVA-11297
算是写的第一个树套树的题目吧
实际上这种数据结构套数据结构,也就是在某种数据结构的每一个节点,注意是每一个节点,而不是底层的节点重新写一套结构。本质上其实也就是普通线段树,就是对每个节点的pushup操作都必须重新构建,并且要严格注意调用的先后顺序。

int a[600][600];
int tree_maxx[2050][2050];
int tree_minn[2050][2050];
int n,m;

void build_y(int id,int fa_l,int fa_r,int l,int r,int k)
{
    if(l==r)
    {
        if(fa_l==fa_r)
        {
            tree_maxx[id][k]=tree_minn[id][k]=a[fa_l][l];
        }
        else
        {
            tree_maxx[id][k]=max(tree_maxx[id<<1][k],tree_maxx[id<<1|1][k]);
            tree_minn[id][k]=min(tree_minn[id<<1][k],tree_minn[id<<1|1][k]);
        }
        return;
    }
    int mid=(l+r)/2;
    build_y(id,fa_l,fa_r,l,mid,ls);
    build_y(id,fa_l,fa_r,mid+1,r,rs);
    tree_maxx[id][k]=max(tree_maxx[id][ls],tree_maxx[id][rs]);//其实是pushup
    tree_minn[id][k]=min(tree_minn[id][ls],tree_minn[id][rs]);
}

void build_x(int l,int r,int k)
{
    if(l==r)
    {
        build_y(k,l,r,1,n,1);
        return;
    }
    int mid=(l+r)/2;
    build_x(l,mid,ls);
    build_x(mid+1,r,rs);
    build_y(k,l,r,1,n,1);//类似pushup
}

void updata_y(int id,int l,int r,int k,int ll,int rr,int fa_l,int fa_r,int val)
{
    if(ll<=l&&r<=rr)
    {
        if(fa_l==fa_r)
        {
            tree_maxx[id][k]=tree_minn[id][k]=val;
        }
        else
        {
            tree_maxx[id][k]=max(tree_maxx[id<<1][k],tree_maxx[id<<1|1][k]);
            tree_minn[id][k]=min(tree_minn[id<<1][k],tree_minn[id<<1|1][k]);
        }
        return;
    }
    int mid=(l+r)/2;
    if(ll<=mid)
    {
        updata_y(id,l,mid,ls,ll,rr,fa_l,fa_r,val);
    }
    if(rr>mid)
    {
        updata_y(id,mid+1,r,rs,ll,rr,fa_l,fa_r,val);
    }
    tree_maxx[id][k]=max(tree_maxx[id][ls],tree_maxx[id][rs]);
    tree_minn[id][k]=min(tree_minn[id][ls],tree_minn[id][rs]);
}


void updata_x(int l,int r,int k,int ll,int rr,int high,int below,int val)
{
    if(ll<=l&&r<=rr)
    {
        updata_y(k,1,n,1,high,below,l,r,val);
        return;
    }
    int mid=(l+r)/2;
    if(ll<=mid)
    {
        updata_x(l,mid,ls,ll,rr,high,below,val);
    }
    if(rr>mid)
    {
        updata_x(mid+1,r,rs,ll,rr,high,below,val);
    }
    updata_y(k,1,n,1,high,below,l,r,val);
    return ;
}
int maxx,minn;

void query_y(int id,int l,int r,int k,int ll,int rr)
{
    if(ll<=l&&r<=rr)
    {
        maxx=max(maxx,tree_maxx[id][k]);
        minn=min(minn,tree_minn[id][k]);
        return ;
    }
    int mid=(l+r)/2;
    if(ll<=mid)
    {
        query_y(id,l,mid,ls,ll,rr);
    }
    if(rr>mid)
    {
        query_y(id,mid+1,r,rs,ll,rr);
    }
}


void query_x(int l,int r,int k,int ll,int rr,int hight,int below)
{
    if(ll<=l&&r<=rr)
    {
        query_y(k,1,n,1,hight,below);
        return;
    }
    int mid=(l+r)/2;
    if(ll<=mid) query_x(l,mid,ls,ll,rr,hight,below);
    if(rr>mid) query_x(mid+1,r,rs,ll,rr,hight,below);
}



signed main()
{
//    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    build_x(1,n,1);
    int q;
    scanf("%d",&q);
    while(q--)
    {
        char s[3];
        scanf("%s",s);
        if(s[0]=='q')
        {
            int xl,yl,xr,yr;
            scanf("%d %d %d %d",&xl,&yl,&xr,&yr);
            maxx=-inf,minn=inf;
            query_x(1,n,1,xl,xr,yl,yr);
            printf("%d %d\n",maxx,minn);
        }
        else
        {
            int x,y,va;
            scanf("%d %d %d",&x,&y,&va);
            updata_x(1,n,1,x,x,y,y,va);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值