bzoj 1513 [POI2006]Tet-Tetris 3D(二维线段树)

 

1513: [POI2006]Tet-Tetris 3D

Time Limit: 30 Sec  Memory Limit: 162 MB
Submit: 540  Solved: 175
[Submit][Status]

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

Sample Output

6

 

【思路】

       线段树套线段树

       第二维的每一维都是一棵线段树,两者操作相似。

 

【代码】

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 const int N = 3*1e3+10;
 6 
 7 int D,S,n;
 8 int ql,qr,qd,qu;
 9 
10 struct segx{
11     int v[N],setv[N];
12     void change(int u,int L,int R,int l,int r,int x) {
13         v[u]=max(v[u],x);
14         if(l<=L && R<=r) setv[u]=x;
15         else {
16             int M=(L+R)>>1;
17             if(l<=M) change(u<<1,L,M,l,r,x);
18             if(M<r)  change(u<<1|1,M+1,R,l,r,x);
19         }
20     }
21     int query(int u,int L,int R,int l,int r) {
22         if(l<=L && R<=r) return v[u];
23         else {
24             int M=(L+R)>>1,ans=setv[u];
25             if(l<=M) ans=max(ans,query(u<<1,L,M,l,r));
26             if(M<r)  ans=max(ans,query(u<<1|1,M+1,R,l,r));
27             return ans;
28         }
29     }
30 };
31 struct segy{
32     segx v[N],setv[N];
33     void change(int u,int L,int R,int l,int r,int x) {
34         v[u].change(1,1,S,qd,qu,x);
35         if(l<=L && R<=r) setv[u].change(1,1,S,qd,qu,x);
36         else {
37             int M=(L+R)>>1;
38             if(l<=M) change(u<<1,L,M,l,r,x);
39             if(M<r)  change(u<<1|1,M+1,R,l,r,x);
40         }
41     }
42     int query(int u,int L,int R,int l,int r) {
43         if(l<=L && R<=r) return v[u].query(1,1,S,qd,qu);
44         else {
45             int M=(L+R)>>1,ans=setv[u].query(1,1,S,qd,qu);
46             if(l<=M) ans=max(ans,query(u<<1,L,M,l,r));
47             if(M<r)  ans=max(ans,query(u<<1|1,M+1,R,l,r));
48             return ans;
49         }
50     }
51 }T;
52 
53 int main() {
54     scanf("%d%d%d",&D,&S,&n);
55     int d,s,w,x,y;
56     for(int i=0;i<n;i++) {
57         scanf("%d%d%d%d%d",&d,&s,&w,&x,&y);
58         ql=x+1,qr=x+d,qd=y+1,qu=y+s;
59         int h=T.query(1,1,D,ql,qr);
60         T.change(1,1,D,ql,qr,h+w);
61     }
62     qd=1,qu=S,ql=1,qr=D;
63     printf("%d",T.query(1,1,D,ql,qr));
64     return 0;
65 }

 

你可能感兴趣的:(bzoj 1513 [POI2006]Tet-Tetris 3D(二维线段树))