传送门biu~
对于线段树套线段树,因为标记的update和pushdown操作过于繁琐,所以采用标记永久化,即在一个节点打上标记后,所有越过这个节点的查询均计算上标记。
Ac代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3005;
int D,S,n,ql,qr,qd,qu;
struct NodeX{
int v[N],lazy[N];
void Modify(int num,int l,int r,int L,int R,int x){
v[num]=max(v[num],x);
if(l==L && r==R) {lazy[num]=max(lazy[num],x);return;}
int mid=l+r>>1;
if(R<=mid) Modify(num<<1,l,mid,L,R,x);
else if(L>mid) Modify(num<<1|1,mid+1,r,L,R,x);
else Modify(num<<1,l,mid,L,mid,x),Modify(num<<1|1,mid+1,r,mid+1,R,x);
}
int Query(int num,int l,int r,int L,int R){
if(l==L && r==R) return v[num];
int mid=l+r>>1,re=lazy[num];
if(R<=mid) return max(re,Query(num<<1,l,mid,L,R));
else if(L>mid) return max(re,Query(num<<1|1,mid+1,r,L,R));
else return max(re,max(Query(num<<1,l,mid,L,mid),Query(num<<1|1,mid+1,r,mid+1,R)));
}
};
struct NodeY{
NodeX v[N],lazy[N];
void Modify(int num,int l,int r,int L,int R,int x){
v[num].Modify(1,1,S,qd,qu,x);
if(l==L && r==R) {lazy[num].Modify(1,1,S,qd,qu,x);return;}
int mid=l+r>>1;
if(R<=mid) Modify(num<<1,l,mid,L,R,x);
else if(L>mid) Modify(num<<1|1,mid+1,r,L,R,x);
else Modify(num<<1,l,mid,L,mid,x),Modify(num<<1|1,mid+1,r,mid+1,R,x);
}
int Query(int num,int l,int r,int L,int R){
if(l==L && r==R) return v[num].Query(1,1,S,qd,qu);
int mid=l+r>>1,re=lazy[num].Query(1,1,S,qd,qu);
if(R<=mid) return max(re,Query(num<<1,l,mid,L,R));
else if(L>mid) return max(re,Query(num<<1|1,mid+1,r,L,R));
else return max(re,max(Query(num<<1,l,mid,L,mid),Query(num<<1|1,mid+1,r,mid+1,R)));
}
}tree;
int main(){
scanf("%d%d%d",&D,&S,&n);
while(n--){
int d,s,w,x,y;
scanf("%d%d%d%d%d",&d,&s,&w,&x,&y);
ql=x+1;qr=x+d;qd=y+1;qu=y+s;
int tmp=tree.Query(1,1,D,ql,qr);
tree.Modify(1,1,D,ql,qr,tmp+w);
}
qd=1,qu=S;
printf("%d\n",tree.Query(1,1,D,1,D));
return 0;
}
别想了亲测四分树过不了这道题的QAQ:
//注意非Ac代码
#include<bits/stdc++.h>
using namespace std;
struct Node{
Node *ch[4];
int v,mark;
Node(){v=mark=0;for(int i=0;i<4;++i)ch[i]=NULL;}
}*root;
void Modify(Node *&o,int l,int r,int d,int u,int L,int R,int D,int U,int x){
if(!o) o=new Node;
o->v=max(o->v,x);
if(l==L && r==R && d==D && u==U) {o->mark=x;return;}
int xm=l+r>>1,ym=d+u>>1;
if(L<=xm && D<=ym) Modify(o->ch[0],l,xm,d,ym,L,min(R,xm),D,min(U,ym),x);
if(L<=xm && U>ym) Modify(o->ch[1],l,xm,ym+1,u,L,min(R,xm),max(D,ym+1),U,x);
if(R>xm && D<=ym) Modify(o->ch[2],xm+1,r,d,ym,max(L,xm+1),R,D,min(U,ym),x);
if(R>xm && U>ym) Modify(o->ch[3],xm+1,r,ym+1,u,max(L,xm+1),R,max(D,ym+1),U,x);
}
int Query(Node *o,int l,int r,int d,int u,int L,int R,int D,int U){
if(!o) return 0;
if(l==L && r==R && d==D && u==U) return o->v;
int xm=l+r>>1,ym=d+u>>1;
int re=o->mark;
if(L<=xm && D<=ym) re=max(re,Query(o->ch[0],l,xm,d,ym,L,min(R,xm),D,min(U,ym)));
if(L<=xm && U>ym) re=max(re,Query(o->ch[1],l,xm,ym+1,u,L,min(R,xm),max(D,ym+1),U));
if(R>xm && D<=ym) re=max(re,Query(o->ch[2],xm+1,r,d,ym,max(L,xm+1),R,D,min(U,ym)));
if(R>xm && U>ym) re=max(re,Query(o->ch[3],xm+1,r,ym+1,u,max(L,xm+1),R,max(D,ym+1),U));
return re;
}
int main(){
int n,m,T;
scanf("%d%d%d",&n,&m,&T);
while(T--){
int d,s,w,x,y;
scanf("%d%d%d%d%d",&d,&s,&w,&x,&y);
int L=x+1,R=x+d,D=y+1,U=y+s;
int tmp=Query(root,1,n,1,m,L,R,D,U);
Modify(root,1,n,1,m,L,R,D,U,tmp+w);
}
printf("%d\n",root->v);
return 0;
}