[POI2006]TET-Tetris 3D

题目

二维线段树板子题啊

但是惊讶的发现我不会打标记

毕竟内层是线段树不能\(pushup\)也不能\(pushdown\)

于是考虑一下标记永久化

其实非常显然\(mx_i\)表示区间最大值,\(tag_i\)表示标记

我们修改的时候一路修改最大值,最后打标记

查询的时候一路查\(tag_i\),最后访问一下\(mx_i\)

非常好理解,因为打上标记之后就表示这棵树内部都受这个标记的影响

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
#define re register
inline int read() {
    char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
inline int max(int a,int b) {return (a>b)?a:b;}
int l[3005],r[3005];
int n,m,Q;
void build(int x,int y,int i) {
    l[i]=x;r[i]=y;if(x==y) return;
    int mid=x+y>>1;
    build(x,mid,i<<1),build(mid+1,y,i<<1|1);
}
struct Seg {
    int d[3005],tag[3005];
    void change(int x,int y,int i,int val) {
        d[i]=max(d[i],val);
        if(x<=l[i]&&y>=r[i]) {tag[i]=max(tag[i],val);return;}
        int mid=l[i]+r[i]>>1;
        if(x<=mid) change(x,y,i<<1,val);
        if(y>=mid+1) change(x,y,i<<1|1,val);
    }
    int query(int x,int y,int i) {
        if(x<=l[i]&&y>=r[i]) return d[i];
        int mid=l[i]+r[i]>>1;int res=tag[i];
        if(x<=mid) res=max(res,query(x,y,i<<1));
        if(y>=mid+1) res=max(res,query(x,y,i<<1|1));
        return res;
    }
};
struct Tree {
    Seg d[3005],tag[3005];
    void change(int x,int y,int l,int r,int i,int val,int xx,int yy) {
        d[i].change(xx,yy,1,val);
        if(x<=l&&y>=r) {tag[i].change(xx,yy,1,val);return;}
        int mid=l+r>>1;
        if(x<=mid) change(x,y,l,mid,i<<1,val,xx,yy);
        if(y>=mid+1) change(x,y,mid+1,r,i<<1|1,val,xx,yy);
    }
    int query(int x,int y,int l,int r,int i,int xx,int yy) {
        if(x<=l&&y>=r) return d[i].query(xx,yy,1);
        int mid=l+r>>1;int res=tag[i].query(xx,yy,1);
        if(x<=mid) res=max(res,query(x,y,l,mid,i<<1,xx,yy));
        if(y>=mid+1) res=max(res,query(x,y,mid+1,r,i<<1|1,xx,yy));
        return res;
    }
}T;
int main() {
    n=read(),m=read();Q=read();
    build(1,m,1);int x,y,s,w,d;
    while(Q--) {
        d=read(),s=read(),w=read(),x=read()+1,y=read()+1;
        int t=T.query(x,x+d-1,1,n,1,y,y+s-1);
        T.change(x,x+d-1,1,n,1,t+w,y,y+s-1);
    }
    printf("%d\n",T.query(1,n,1,n,1,1,m));
    return 0;
}
posted @ 2019-03-12 17:46  asuldb  阅读(188)  评论(0编辑  收藏  举报