1. 程式人生 > >BZOJ1513 [POI2006]Tet-Tetris 3D 【二維線段樹】

BZOJ1513 [POI2006]Tet-Tetris 3D 【二維線段樹】

get mem HR void 修改 mod 3D 理解 fine

題目鏈接

BZOJ1513

題解

真正地理解了一波線段樹標記永久化的姿勢
每個節點維護兩個值\(v\)\(tag\)
\(v\)代表兒子中的最值
\(tag\)代表未下傳的最值

顯然節點的區間大於等於\(v\)的實際區間
\(tag\)的區間包含節點的區間

我們在修改的時候,沿路\(v\)都要修改,底層\(tag\)修改

我們在查詢的時候,沿路\(tag\)都要查詢,底層\(v\)查詢

\(upd:\)理解層面上看,和普通線段樹是一樣的嘛,,,,

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio> #include<cmath> #include<map> #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt) #define REP(i,n) for (int i = 1; i <= (n); i++) #define mp(a,b) make_pair<int,int>(a,b) #define cls(s) memset(s,0,sizeof(s)) #define cp pair<int,int> #define LL long long int
#define ls (u << 1) #define rs (u << 1 | 1) using namespace std; const int maxn = 4005,maxm = 5000005,INF = 1000000000; inline int read(){ int out = 0,flag = 1; char c = getchar(); while (c < 48 || c > 57){if (c == ‘-‘) flag = -1; c = getchar();} while (c >= 48 && c <= 57
){out = (out << 3) + (out << 1) + c - 48; c = getchar();} return out * flag; } int n,D,S; struct segx{ int mx[maxm],lc[maxm],rc[maxm],tag[maxm],cnt; void modify(int& u,int l,int r,int L,int R,int v){ if (!u) u = ++cnt; mx[u] = max(mx[u],v); if (l >= L && r <= R){tag[u] = max(tag[u],v); return;} int mid = l + r >> 1; if (mid >= L) modify(lc[u],l,mid,L,R,v); if (mid < R) modify(rc[u],mid + 1,r,L,R,v); } int query(int u,int l,int r,int L,int R){ if (!u) return 0; if (l >= L && r <= R) return mx[u]; int mid = l + r >> 1,ans = tag[u]; if (mid >= R) return max(ans,query(lc[u],l,mid,L,R)); if (mid < L) return max(ans,query(rc[u],mid + 1,r,L,R)); return max(ans,max(query(lc[u],l,mid,L,R),query(rc[u],mid + 1,r,L,R))); } }Seg; struct segy{ int rt[maxn],tag[maxn]; void modify(int u,int l,int r,int L,int R,int ll,int rr,int v){ Seg.modify(rt[u],1,S,ll,rr,v); if (l >= L && r <= R){Seg.modify(tag[u],1,S,ll,rr,v); return;} int mid = l + r >> 1; if (mid >= L) modify(ls,l,mid,L,R,ll,rr,v); if (mid < R) modify(rs,mid + 1,r,L,R,ll,rr,v); } int query(int u,int l,int r,int L,int R,int ll,int rr){ if (l >= L && r <= R) return Seg.query(rt[u],1,S,ll,rr); int mid = l + r >> 1,ans = Seg.query(tag[u],1,S,ll,rr); if (mid >= L) ans = max(ans,query(ls,l,mid,L,R,ll,rr)); if (mid < R) ans = max(ans,query(rs,mid + 1,r,L,R,ll,rr)); return ans; } }T; int main(){ D = read(); S = read(); n = read(); int d,s,h,x0,y0,x,y,xx,yy; while (n--){ d = read(); s = read(); h = read(); x0 = read(); y0 = read(); x = x0 + 1; y = y0 + 1; xx = x0 + d; yy = y0 + s; h += T.query(1,1,D,x,xx,y,yy); T.modify(1,1,D,x,xx,y,yy,h); } printf("%d\n",T.query(1,1,D,1,D,1,S)); return 0; }

BZOJ1513 [POI2006]Tet-Tetris 3D 【二維線段樹】