标记永久化对于线段树上每个节点需要维护两个量,拿维护最大值来举例,你需要维护一个值have,代表这个子树里有这样一个最大值,另外一个值all代表这个子树里全都是这个值
#include
#include
#include
#include
#define N 1010
#define M 3
using namespace std;
int D,S;
struct INSSEG
{
int all[N*M],hav[N*M];
void change(int now,int l,int r,int ll,int rr,int v)
{
hav[now]=max(hav[now],v);
if(ll==l&&rr==r)
{
all[now]=max(v,all[now]);
return;
}
int mid=(l+r)>>1;
if(rr<=mid) change(now<<1,l,mid,ll,rr,v);
else if(ll>mid) change(now<<1|1,mid+1,r,ll,rr,v);
else change(now<<1,l,mid,ll,mid,v),change(now<<1|1,mid+1,r,mid+1,rr,v);
}
int check(int now,int l,int r,int ll,int rr)
{
if(ll==l&&rr==r) return hav[now];
int ret=all[now];
int mid=(l+r)>>1;
if(rr<=mid) ret=max(ret,check(now<<1,l,mid,ll,rr));
else if(ll>mid) ret=max(ret,check(now<<1|1,mid+1,r,ll,rr));
else ret=max(ret,max(check(now<<1,l,mid,ll,mid),check(now<<1|1,mid+1,r,mid+1,rr)));
return ret;
}
};
struct OUSSEG
{
INSSEG all[N*M],hav[N*M];
void change(int now,int l,int r,int ll,int rr,int lll,int rrr,int v)
{
hav[now].change(1,0,S,lll,rrr,v);
if(ll<=l&&rr>=r)
{
all[now].change(1,0,S,lll,rrr,v);
return;
}
int mid=(l+r)>>1;
if(rr<=mid) change(now<<1,l,mid,ll,rr,lll,rrr,v);
else if(ll>mid) change(now<<1|1,mid+1,r,ll,rr,lll,rrr,v);
else change(now<<1,l,mid,ll,mid,lll,rrr,v),change(now<<1|1,mid+1,r,mid+1,rr,lll,rrr,v);
}
int check(int now,int l,int r,int ll,int rr,int lll,int rrr)
{
if(ll<=l&&rr>=r) return hav[now].check(1,0,S,lll,rrr);
int ret=all[now].check(1,0,S,lll,rrr);
int mid=(l+r)>>1;
if(rr<=mid) ret=max(ret,check(now<<1,l,mid,ll,rr,lll,rrr));
else if(ll>mid) ret=max(ret,check(now<<1|1,mid+1,r,ll,rr,lll,rrr));
else ret=max(ret,max(check(now<<1,l,mid,ll,mid,lll,rrr),check(now<<1|1,mid+1,r,mid+1,rr,lll,rrr)));
return ret;
}
}O;
int main()
{
int n;
scanf("%d%d%d",&D,&S,&n);
int d,s,w,x,y;
while(n--)
{
scanf("%d%d%d%d%d",&d,&s,&w,&x,&y);
int most=O.check(1,0,D,x+1,x+d,y+1,y+s);
O.change(1,0,D,x+1,x+d,y+1,y+s,most+w);
}
printf("%d",O.check(1,0,D,0,D,0,S));
}