6
【思路】
线段树套线段树
第二维的每一维都是一棵线段树,两者操作相似。
【代码】
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 const int N = 3*1e3+10; 6 7 int D,S,n; 8 int ql,qr,qd,qu; 9 10 struct segx{ 11 int v[N],setv[N]; 12 void change(int u,int L,int R,int l,int r,int x) { 13 v[u]=max(v[u],x); 14 if(l<=L && R<=r) setv[u]=x; 15 else { 16 int M=(L+R)>>1; 17 if(l<=M) change(u<<1,L,M,l,r,x); 18 if(M<r) change(u<<1|1,M+1,R,l,r,x); 19 } 20 } 21 int query(int u,int L,int R,int l,int r) { 22 if(l<=L && R<=r) return v[u]; 23 else { 24 int M=(L+R)>>1,ans=setv[u]; 25 if(l<=M) ans=max(ans,query(u<<1,L,M,l,r)); 26 if(M<r) ans=max(ans,query(u<<1|1,M+1,R,l,r)); 27 return ans; 28 } 29 } 30 }; 31 struct segy{ 32 segx v[N],setv[N]; 33 void change(int u,int L,int R,int l,int r,int x) { 34 v[u].change(1,1,S,qd,qu,x); 35 if(l<=L && R<=r) setv[u].change(1,1,S,qd,qu,x); 36 else { 37 int M=(L+R)>>1; 38 if(l<=M) change(u<<1,L,M,l,r,x); 39 if(M<r) change(u<<1|1,M+1,R,l,r,x); 40 } 41 } 42 int query(int u,int L,int R,int l,int r) { 43 if(l<=L && R<=r) return v[u].query(1,1,S,qd,qu); 44 else { 45 int M=(L+R)>>1,ans=setv[u].query(1,1,S,qd,qu); 46 if(l<=M) ans=max(ans,query(u<<1,L,M,l,r)); 47 if(M<r) ans=max(ans,query(u<<1|1,M+1,R,l,r)); 48 return ans; 49 } 50 } 51 }T; 52 53 int main() { 54 scanf("%d%d%d",&D,&S,&n); 55 int d,s,w,x,y; 56 for(int i=0;i<n;i++) { 57 scanf("%d%d%d%d%d",&d,&s,&w,&x,&y); 58 ql=x+1,qr=x+d,qd=y+1,qu=y+s; 59 int h=T.query(1,1,D,ql,qr); 60 T.change(1,1,D,ql,qr,h+w); 61 } 62 qd=1,qu=S,ql=1,qr=D; 63 printf("%d",T.query(1,1,D,ql,qr)); 64 return 0; 65 }