【POI 2006】 Tet-Tetris-3D

【题目链接】

           点击打开链接

【算法】

          二维线段树(树套树)

          注意标记永久化

【代码】

           

#include
using namespace std;
#define MAXD 1000

int D,S,N,d,s,w,x,y,tmp;

struct SegmentTree {
	struct Node {
		int l,r,Max,tag;
	} Tree[MAXD*2+100];
	inline void build(int index,int l,int r) {
		int mid;
		Tree[index].l = l;
		Tree[index].r = r;
		Tree[index].Max = Tree[index].tag = 0;
		mid = (l + r) >> 1;
		if (l == r) return;
		build(index<<1,l,mid);
		build(index<<1|1,mid+1,r);
	}
	inline void pushdown(int index) {
		Tree[index<<1].Max = max(Tree[index<<1].Max,Tree[index].tag);
		Tree[index<<1|1].Max = max(Tree[index<<1|1].Max,Tree[index].tag);
		Tree[index<<1].tag = max(Tree[index<<1].tag,Tree[index].tag);
		Tree[index<<1|1].tag = max(Tree[index<<1|1].tag,Tree[index].tag);
		Tree[index].tag = 0;
	}
	inline void pushup(int index) {
		Tree[index].Max = max(Tree[index<<1].Max,Tree[index<<1|1].Max);
	}
	inline void modify(int index,int l,int r,int val) {
		int mid;
		if (Tree[index].l == l && Tree[index].r == r) {
			Tree[index].Max = max(Tree[index].Max,val);
			Tree[index].tag = max(Tree[index].tag,val);
			return;
		}
		pushdown(index); 
		mid = (Tree[index].l + Tree[index].r) >> 1;
		if (mid >= r) modify(index<<1,l,r,val);
		else if (mid + 1 <= l) modify(index<<1|1,l,r,val);
		else {
			modify(index<<1,l,mid,val);
			modify(index<<1|1,mid+1,r,val);
		}
		pushup(index);
	}
	inline int query(int index,int l,int r) {
		int mid;
		if (Tree[index].l == l && Tree[index].r == r) return Tree[index].Max;
		pushdown(index);
		mid = (Tree[index].l + Tree[index].r) >> 1;
		if (mid >= r) return query(index<<1,l,r);
		else if (mid + 1 <= l) return query(index<<1|1,l,r);
		else return max(query(index<<1,l,mid),query(index<<1|1,mid+1,r));
	}
};

struct SegmentTree2D {
	struct Node {
		int l,r;
		SegmentTree Max,tag;
	} Tree[MAXD*2+100]; 
	inline void build(int index,int l,int r) {
		int mid;
		Tree[index].l = l; 
		Tree[index].r = r;
		Tree[index].Max.build(1,0,S);
		Tree[index].tag.build(1,0,S);
		mid = (l + r) >> 1;
		if (l == r) return;
		build(index<<1,l,mid);
		build(index<<1|1,mid+1,r);
	} 
	inline void modify(int index,int l1,int r1,int l2,int r2,int val) {
		int mid;
		Tree[index].Max.modify(1,l2,r2,val);                                                                                                                                                                                                                                                           
		if (Tree[index].l == l1 && Tree[index].r == r1) {
			Tree[index].tag.modify(1,l2,r2,val);
			return;
		}
		mid = (Tree[index].l + Tree[index].r) >> 1;
		if (mid >= r1) modify(index<<1,l1,r1,l2,r2,val);
		else if (mid + 1 <= l1) modify(index<<1|1,l1,r1,l2,r2,val);
		else {
			modify(index<<1,l1,mid,l2,r2,val);
			modify(index<<1|1,mid+1,r1,l2,r2,val);
		}
	}
	inline int query(int index,int l1,int r1,int l2,int r2) {
		int mid,ret = 0;
		ret = Tree[index].tag.query(1,l2,r2);
		if (Tree[index].l == l1 && Tree[index].r == r1) return max(ret,Tree[index].Max.query(1,l2,r2));
		mid = (Tree[index].l + Tree[index].r) >> 1;
		if (mid >= r1) return max(ret,query(index<<1,l1,r1,l2,r2));
		else if (mid + 1 <= l1) return max(ret,query(index<<1|1,l1,r1,l2,r2));
		else return max(ret,max(query(index<<1,l1,mid,l2,r2),query(index<<1|1,mid+1,r1,l2,r2)));
	}
} T;

template  inline void read(T &x) {
	int f = 1; x = 0;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
	for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
	x *= f; 
}
template  inline void write(T x) {
	if (x < 0) { putchar('-'); x = -x; }
	if (x > 9) write(x/10);
	putchar(x%10+'0');
}
template  inline void writeln(T x) {
	write(x);
	puts("");	
}

int main() {
	
	read(D); read(S); read(N);
	T.build(1,0,D);
	while (N--) {
		read(d); read(s); read(w); read(x); read(y);
		tmp = T.query(1,x+1,x+d,y+1,y+s);
		T.modify(1,x+1,x+d,y+1,y+s,tmp+w);
	}
	
	writeln(T.query(1,0,D,0,S));
		
	return 0;
}

你可能感兴趣的:(线段树,树套树)