BZOJ1513:[POI2006]TET-Tetris 3D(线段树套线段树)
Description
Task: Tetris 3D "Tetris" 游戏的作者决定做一个新的游戏, 一个三维的版本, 在里面很多立方体落在平面板,一个立方体开始落下直到碰上一个以前落下的立方体或者落地即停止. 作者想改变一下游戏的目的使得它更大众化,在新游戏中你将知道落下的立方体信息以及位置,你的任务就是回答所有立方体落下后最高的方块的高度.所有的立方体在下落过程中都是垂直的并且不会旋转.平板左下角坐标为原点,并且平行于坐标轴.
Input
第一行给出三个整数 D, S and N ( 1<= N<= 20 000, 1<= D, S <=1 000), 分别表示平板的长和宽以及下落立方体的数目. 接下来N 行每行描述一个立方体. 每行包含5个整数: d, s, w, x and y (1<= d, 0 <=x, d + x<= D, 1 <=s, 0<= y, s + y<= S, 1<= w <=100 000), 分别表示立方体的长\宽\高以及落下的左下角坐标, 长和宽都是平行于平板坐标轴的,落下后立方体着地的四个角坐标分别为: (x, y), (x + d, y), (x, y + s) and (x + d, y + s).
Output
一个整数表示所有立方体落下后最高的方块的高度.
Sample Input
7 5 4
4 3 2 0 0
3 3 1 3 0
7 1 2 0 3
2 3 3 2 2
4 3 2 0 0
3 3 1 3 0
7 1 2 0 3
2 3 3 2 2
Sample Output
6
Solution
区间修改,必须标记永久化
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define INF (0x7fffffff) 5 using namespace std; 6 7 int D,S,N,d,s,h,x,y; 8 9 struct Treey 10 { 11 int Segt[3010],mark[3010]; 12 void Update(int node,int l,int r,int l1,int r1,int k) 13 { 14 if (l>r1 || r<l1) return; 15 Segt[node]=max(Segt[node],k); 16 if (l1<=l && r<=r1) 17 { 18 mark[node]=max(mark[node],k); 19 return; 20 } 21 int mid=(l+r)/2; 22 Update(node*2,l,mid,l1,r1,k); 23 Update(node*2+1,mid+1,r,l1,r1,k); 24 } 25 int Query(int node,int l,int r,int l1,int r1) 26 { 27 if (l>r1 || r<l1) return -INF; 28 if (l1<=l && r<=r1) 29 return Segt[node]; 30 int mid=(l+r)/2,ans=mark[node]; 31 int t=max(Query(node*2,l,mid,l1,r1),Query(node*2+1,mid+1,r,l1,r1)); 32 return max(t,ans); 33 } 34 }; 35 36 struct Treex 37 { 38 Treey Segt[3010],mark[3010]; 39 void Update(int node,int l,int r,int l1,int r1,int l2,int r2,int k) 40 { 41 if (l>r1 || r<l1) return; 42 Segt[node].Update(1,0,D,l2,r2,k); 43 if (l1<=l && r<=r1) 44 { 45 mark[node].Update(1,0,D,l2,r2,k); 46 return; 47 } 48 int mid=(l+r)/2; 49 Update(node*2,l,mid,l1,r1,l2,r2,k); 50 Update(node*2+1,mid+1,r,l1,r1,l2,r2,k); 51 } 52 int Query(int node,int l,int r,int l1,int r1,int l2,int r2) 53 { 54 if (l>r1 || r<l1) return -INF; 55 if (l1<=l && r<=r1) 56 return Segt[node].Query(1,0,D,l2,r2); 57 int mid=(l+r)/2,ans=mark[node].Query(1,0,D,l2,r2); 58 int t=max(Query(node*2,l,mid,l1,r1,l2,r2),Query(node*2+1,mid+1,r,l1,r1,l2,r2)); 59 return max(t,ans); 60 } 61 }T; 62 63 int main() 64 { 65 scanf("%d%d%d",&D,&S,&N); 66 for (int i=1;i<=N;++i) 67 { 68 scanf("%d%d%d%d%d",&d,&s,&h,&x,&y); 69 int maxn=T.Query(1,0,D,x,x+d-1,y,y+s-1); 70 T.Update(1,0,D,x,x+d-1,y,y+s-1,maxn+h); 71 } 72 printf("%d",T.Query(1,0,D,0,D,0,D)); 73 }