【题目链接】
点击打开链接
【算法】
二维线段树(树套树)
注意标记永久化
【代码】
#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;
}