题目大意:三维俄罗斯方块,问最后摞了多高。
思路:二维线段树的裸题。但是要注意二维线段树不支持标记下穿。所以就不下传,每次更新答案的时候先看标记,然后用所有的跟标记比较大小之后返回。
具体看代码吧,不知道怎么说。
CODE:
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #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; }