【题目链接】
【算法】
二维线段树(树套树)
注意标记永久化
【代码】
#include<bits/stdc++.h> 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 <typename T> 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 <typename T> inline void write(T x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x/10); putchar(x%10+'0'); } template <typename T> 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; }