[POI2006] TET-Tetris 3D

题目描述:

写一个数据结构,支持查询一个矩形的最大值 并将这个矩形的值全部变为 这个最大值加一个常数

题目分析:

二维线段树+标记永久化
maxi表示子树内的一个最大值,tag表示子树全部都被覆盖的值…

题目链接:

Luogu 3437

Ac 代码:

#include 
#include 
#include 
#include 
int Maxx,Maxy,n;
struct inside_seg{
    int maxi[4005],tag[4005];
    void modify(int o,int l,int r,int ql,int qr,int k)
    {
        maxi[o]=std::max(maxi[o],k);
        if(ql<=l&&r<=qr) return (void)(tag[o]=std::max(tag[o],k));
        int mid=(l+r)>>1;
        if(ql<=mid) modify((o<<1),l,mid,ql,qr,k);
        if(qr>mid) modify((o<<1)|1,mid+1,r,ql,qr,k);
    }
    int ask(int o,int l,int r,int ql,int qr)
    {
        if(ql<=l&&r<=qr) return std::max(tag[o],maxi[o]);
        int mid=(l+r)>>1;
        int ans=tag[o];
        if(ql<=mid) ans=std::max(ans,ask((o<<1),l,mid,ql,qr));
        if(qr>mid) ans=std::max(ans,ask((o<<1)|1,mid+1,r,ql,qr));
        return ans;
    }
};
struct external_seg{
    inside_seg maxi[4005],tag[4005];
    void modify(int o,int l,int r,int ql,int qr,int y1,int y2,int k)
    {
        maxi[o].modify(1,0,Maxy,y1,y2,k);
        if(ql<=l&&r<=qr) return (void)(tag[o].modify(1,0,Maxy,y1,y2,k));
        int mid=(l+r)>>1;
        if(ql<=mid) modify((o<<1),l,mid,ql,qr,y1,y2,k);
        if(qr>mid) modify((o<<1)|1,mid+1,r,ql,qr,y1,y2,k);
    }
    int ask(int o,int l,int r,int ql,int qr,int y1,int y2)
    {
        if(ql<=l&&r<=qr) return maxi[o].ask(1,0,Maxy,y1,y2);
        int mid=(l+r)>>1;
        int ans=tag[o].ask(1,0,Maxy,y1,y2);
        if(ql<=mid) ans=std::max(ans,ask((o<<1),l,mid,ql,qr,y1,y2));
        if(qr>mid) ans=std::max(ans,ask((o<<1)|1,mid+1,r,ql,qr,y1,y2));
        return ans;
    }
}T;
int main()
{
    scanf("%d%d%d",&Maxx,&Maxy,&n);
    for(int i=1,d,s,h,x,y;i<=n;i++)
    {
        scanf("%d%d%d%d%d",&d,&s,&h,&x,&y);
        h+=T.ask(1,0,Maxx,x,x+d-1,y,y+s-1);
        T.modify(1,0,Maxx,x,x+d-1,y,y+s-1,h);
    }
    printf("%d\n",T.ask(1,0,Maxx,0,Maxx,0,Maxy));
    return 0;
}

你可能感兴趣的:(题目分析,二维线段树,树套树)