树套树+UVALive6709 Mosaic 二维线段树

Posted lhclqslove

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树套树+UVALive6709 Mosaic 二维线段树相关的知识,希望对你有一定的参考价值。

题目链接:6709 Mosaic 

题解:参考这个博客:二维线段树,先按行建树然后每一个节点也是一个棵线段树按列建。

#include<bits/stdc++.h>
#include<cmath>
#include<set>
#include<cstdio>
#include<iomanip>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
using namespace std;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef pair<int,int>pii;
const int mod=1e9+9;
const int INF=0x4f4f4f4f;
const int base=13331;
const ll inf=1e18+100;
const int maxn=800;
int n,m,cnt,num[maxn+5][maxn+5],t;
struct segmentxy
{
    int MIN[(maxn<<2)+5][(maxn<<2)+5],MAX[(maxn<<2)+5][(maxn<<2)+5],lx,rx,ly,ry,fa,is_leaf,px,py,val;//fa是当前x树的根,is判断是否为叶节点的树
    void pushupx(int fa,int p)//更新行
    {
        MIN[fa][p]=min(MIN[fa<<1][p],MIN[fa<<1|1][p]);
        MAX[fa][p]=max(MAX[fa<<1][p],MAX[fa<<1|1][p]);
    }
    void pushupy(int fa,int p)//更新列
    {
        MIN[fa][p]=min(MIN[fa][p<<1],MIN[fa][p<<1|1]);
        MAX[fa][p]=max(MAX[fa][p<<1],MAX[fa][p<<1|1]);
    }
    void buildy(int l,int r,int rt,int *a)
    {
        if(l==r){if(is_leaf)MAX[fa][rt]=MIN[fa][rt]=a[l];else pushupx(fa,rt);return;}
        int m=(l+r)>>1;
        buildy(ls,a);buildy(rs,a);
        pushupy(fa,rt);
    }
    void buildx(int l,int r,int rt)
    {
        if(l==r){is_leaf=true;fa=rt;buildy(ly,ry,1,num[l]);}
        else
        {
            int m=(l+r)>>1;
            buildx(ls);buildx(rs);
            fa=rt;is_leaf=false;buildy(ly,ry,1,num[l]);
        }
    }
    void build(int xl,int xr,int yl,int yr)
    {
        lx=xl;rx=xr;ly=yl;ry=yr;
        buildx(lx,rx,1);
    }
    void updatey(int l,int r,int rt)
    {
        if(l==r){if(is_leaf)MAX[fa][rt]=MIN[fa][rt]=val;else pushupx(fa,rt);return;}
        {
            int m=(l+r)>>1;
            if(py<=m)updatey(ls);
            else updatey(rs);
            pushupy(fa,rt);
        }
    }
    void updatex(int l,int r,int rt)
    {
        if(l==r){is_leaf=true;fa=rt;updatey(1,n,1);return;}
        else
        {
            int m=(l+r)>>1;
            if(px<=m)updatex(ls);
            else updatex(rs);
            is_leaf=false;fa=rt;updatey(1,n,1);
        }
    }
    void update(int x,int y,int z)
    {
        px=x;py=y;val=z;updatex(1,n,1);
    }
    int querymax_y(int l,int r,int rt)
    {
        if(ly<=l&&r<=ry){return MAX[fa][rt];}
        else
        {
            int m=(l+r)>>1,ans=0;
            if(ly<=m)ans=max(ans,querymax_y(ls));
            if(ry>m)ans=max(ans,querymax_y(rs));
            return ans;
        }
    }
    int querymax_x(int l,int r,int rt)
    {
        if(lx<=l&&r<=rx){fa=rt;return querymax_y(1,n,1);}
        else
        {
            int ans=0;int m=(l+r)>>1;fa=rt;
            if(lx<=m)ans=max(ans,querymax_x(ls));
            if(rx>m) ans=max(ans,querymax_x(rs));
            return ans;
        }
    }
    int querymin_y(int l,int r,int rt)
    {
        if(ly<=l&&r<=ry){return MIN[fa][rt];}
        else
        {
            int m=(l+r)>>1,ans=INF;
            if(ly<=m)ans=min(ans,querymin_y(ls));
            if(ry>m)ans=min(ans,querymin_y(rs));
            return ans;
        }
    }
    int querymin_x(int l,int r,int rt)
    {
        if(lx<=l&&r<=rx){fa=rt;return querymin_y(1,n,1);}
        else
        {
            int ans=INF;int m=(l+r)>>1;fa=rt;
            if(lx<=m)ans=min(ans,querymin_x(ls));
            if(rx>m)ans=min(ans,querymin_x(rs));
            return ans;
        }
    }
    int query(int xl,int xr,int yl,int yr)
    {
         lx=xl;rx=xr;ly=yl;ry=yr;
         int an1=querymax_x(1,n,1);
         int an2=querymin_x(1,n,1);
         return (an1+an2)>>1;
    }
}tr;
int main()
{
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++)
    {
        printf("Case #%d:\n",cas);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&num[i][j]);
            }
        }
        tr.build(1,n,1,n);
        scanf("%d",&m);
        while(m--)
        {
            int lx,rx,ly,ry,x,y,z;
            scanf("%d %d %d",&x,&y,&z);z/=2;
            lx=max(0,x-z);rx=min(n,x+z);
            ly=max(0,y-z);ry=min(n,y+z);
            int ans=tr.query(lx,rx,ly,ry);
            printf("%d\n",ans);
            tr.update(x,y,ans);
        }
    }
    return 0;
}

  

以上是关于树套树+UVALive6709 Mosaic 二维线段树的主要内容,如果未能解决你的问题,请参考以下文章

#树套树,二维线段树#HDU 4819 Mosaic

HDU4819 Mosaic树套树

HDU 4819:Mosaic(线段树套线段树)

二维线段树之树套树

知识点 - 线段树 权值 树套树 二维 可持续

[POJ2155] Matrix(二维线段树,树套树)