题目大意:三维俄罗斯方块,问最后摞了多高。
思路:二维线段树的裸题。但是要注意二维线段树不支持标记下穿。所以就不下传,每次更新答案的时候先看标记,然后用所有的跟标记比较大小之后返回。
具体看代码吧,不知道怎么说。
CODE:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#define MAX 1100
using namespace std;
#define LEFT (pos << 1)
#define RIGHT (pos << 1|1)
int X,Y;
struct SegTreeY{ //数据
int tree[MAX << 1],tag[MAX << 1];
int Ask(int l,int r,int x,int y,int pos) {
if(l == x && r == y) return tree[pos];
int mid = (l + r) >> 1,re = tag[pos];
if(y <= mid) return max(re,Ask(l,mid,x,y,LEFT));
if(x > mid) return max(re,Ask(mid + 1,r,x,y,RIGHT));
int left = Ask(l,mid,x,mid,LEFT);
int right = Ask(mid + 1,r,mid + 1,y,RIGHT);
return max(re,max(left,right));
}
void Modify(int l,int r,int x,int y,int c,int pos) {
tree[pos] = max(tree[pos],c);
if(l == x && y == r) {
tag[pos] = max(tag[pos],c);
return ;
}
int mid = (l + r) >> 1;
if(y <= mid) Modify(l,mid,x,y,c,LEFT);
else if(x > mid) Modify(mid + 1,r,x,y,c,RIGHT);
else {
Modify(l,mid,x,mid,c,LEFT);
Modify(mid + 1,r,mid + 1,y,c,RIGHT);
}
}
};
int ask_x,ask_y;
struct SegTreeX{ //寻址
SegTreeY tree[MAX << 1],tag[MAX << 1];
int Ask(int l,int r,int x,int y,int pos) {
if(l == x && y == r)
return tree[pos].Ask(0,Y,ask_x,ask_y,1);
int mid = (l + r) >> 1,re = tag[pos].Ask(0,Y,ask_x,ask_y,1);
if(y <= mid) return max(re,Ask(l,mid,x,y,LEFT));
if(x > mid) return max(re,Ask(mid + 1,r,x,y,RIGHT));
int left = Ask(l,mid,x,mid,LEFT);
int right = Ask(mid + 1,r,mid + 1,y,RIGHT);
return max(re,max(left,right));
}
void Modify(int l,int r,int x,int y,int c,int pos) {
tree[pos].Modify(0,Y,ask_x,ask_y,c,1);
if(l == x && y == r) {
tag[pos].Modify(0,Y,ask_x,ask_y,c,1);
return ;
}
int mid = (l + r) >> 1;
if(y <= mid) Modify(l,mid,x,y,c,LEFT);
else if(x > mid) Modify(mid + 1,r,x,y,c,RIGHT);
else {
Modify(l,mid,x,mid,c,LEFT);
Modify(mid + 1,r,mid + 1,y,c,RIGHT);
}
}
}solver;
int cnt;
int main()
{
cin >> X >> Y >> cnt;
X += 10,Y += 10;
for(int d,s,w,x,y,i = 1; i <= cnt; ++i) {
scanf("%d%d%d%d%d",&d,&s,&w,&x,&y);
ask_x = y,ask_y = y + s - 1;
int height = solver.Ask(0,X,x,x + d - 1,1);
solver.Modify(0,X,x,x + d - 1,height + w,1);
}
ask_x = 0,ask_y = Y;
cout << solver.Ask(0,X,0,X,1) << endl;
return 0;
}