POI2006-BZOJ1513:Tet-Tetris 3D

来源:互联网 发布:淘宝针织衫哪家好 编辑:程序博客网 时间:2024/05/16 15:42

这里写图片描述
题意:给定一个空矩阵,对其进行两种操作:
1.矩阵询问max
2.矩阵赋值
你只需要输出最后的矩阵最大值。
二维线段树……应该是显然的,但是做的时候发现自己Naive了……
首先我们在修改一个子矩阵时,包含子矩阵的那些矩阵的值在外层没办法上传。
其次我们发现子矩阵的子矩阵也没有信息……
忽然想到标记永久化这个东西,想到一种方法大概这样:
比较显然的一点就是,内外层线段树是等效的,所以我们只要不在外层上传信息,下传信息,就”不必“在内层下传信息。
1.在每层线段树我们记录两个值,一个值是完美覆盖该区间的标记Tag,一个值是子树最大值Mx。
我们在修改的时候,可以这样做:
对于外层线段树上的那条修改路径,由于其修改是单增不降的,所以我们可以直接更改那条路径上的Mx,直到修改到某个节点,它被这个修改区间覆盖,这时候我们不仅要修改子树的值,还需要修改它的Tag。
所以,对于修改,我们只需要对于每层的线段树沿途也进行修改即可。
2.对于查询最大值:
我们在查询某个子矩阵的最大值的时候,在路径上显然要查询所有路径上的Tag,对于某个被询问区间覆盖的区间,我们需要查询它的子树值,最后对所有值取max。
特别注意,如果没有特别的数据弱,我们里层需要动态开点。

#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#define Rep(i,n) for(int i = 1; i <= n ; i ++)#define RepG(i,x) for(int i = head[x] ;~ i ; i = edge[i].next)#define Rep_d(i,n) for(int i = n ; i > 0 ; i --)#define Rep_0(i,n) for(int i = 0 ; i < n ; i ++)#define RD(i,x,n) for(int i = x; i <= n ; i ++)#define CLR(a,b) memset(a,b,sizeof(a))#define RDD(i,x,n) for(int i = x; i >= n; i --)#define u t[x]#define lc ch[0]#define rc ch[1]#define v edge[i].to#define ulfc t[u.lc]#define urtc t[u.rc]using namespace std;const int inf = 1 << 30;typedef long long ll;int read(){    char ch = getchar();    while((ch < '0' || ch > '9') && ch != '-')ch = getchar ();    int x = 0;    bool flag = 0;    if(ch == '-')ch = getchar(),flag = 1;    while(ch >= '0' && ch <= '9')x = (x << 1) + (x << 3) + ch - '0',ch = getchar ();    return flag ? -x : x;}const int N = 1005;int n,m,k;#define lson x << 1,l,mid,ql,qr#define rson x << 1 | 1,mid + 1,r,ql,qr#define RT 1,1,n,ql,qr int Ql,Qr;struct Seg{    struct Tree{        int Mx[N * 3],tag[N * 3];        void Modify(int x,int l,int r,int ql,int qr,int s){            Mx[x] = max(Mx[x],s);            if(l >= ql && r <= qr){                tag[x] = max(s,tag[x]);                return ;            }            int mid = l + r >> 1;            if(ql <= mid)Modify(lson,s);            if(mid < qr)Modify(rson,s);        }        int Qry(int x,int l,int r,int ql,int qr){            if(l >= ql && r <= qr)return Mx[x];            int ans = tag[x],mid = l + r >> 1;            if(ql <= mid)ans = max(Qry(lson),ans);            if(mid < qr)ans = max(Qry(rson),ans);            return ans;        }    };    Tree Mx[N * 3],tag[N * 3];    void Modify(int x,int l,int r,int ql,int qr,int s){        Mx[x].Modify(RT,s);        if(l >= Ql && r <= Qr){            tag[x].Modify(RT,s);            return ;        }        int mid = l + r >> 1;        if(Ql <= mid)Modify(lson,s);        if(mid < Qr)Modify(rson,s);    }    int Qry(int x,int l,int r,int ql,int qr){        if(l >= Ql && r <= Qr)            return Mx[x].Qry(RT);        int ans = tag[x].Qry(RT),mid = l + r >> 1;        if(Ql <= mid)ans = max(ans,Qry(lson));        if(mid < Qr)ans = max(ans,Qry(rson));        return ans;    }}seg;int main (){    n = read(),m = read(),k = read();    Rep(i,k)    {        int len,wd,ht,x,y;        len = read(),wd = read(),ht = read(),x = read(),y = read();        Ql = x + 1;        Qr = x + len;        int p;        p = seg.Qry(1,1,n,y + 1,y + wd);        seg.Modify(1,1,n,y + 1,y + wd,p + ht);    }    Ql = 1,Qr = n;    printf("%d\n",seg.Qry(1,1,n,1,n));    return 0;}/*7 5 44 3 2 0 03 3 1 3 07 1 2 0 32 3 3 2 2*/
0 0
原创粉丝点击