二维线段树 算个模板题吧 区间赋值 区间max
一遇到带标记的树套树就蛋疼
怎么说呢
标记永久化 就不用下传了
从根到某个节点的区间上的路径自顶向下顺着递归的顺序修改 就省去了pushup
#include
#include
#include
using namespace std;
typedef long long ll;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=1005;
int D,S,Q;
struct SEGX{
int T[N*3],F[N*3];
void Change(int x,int l,int r,int L,int R,int val){
T[x]=max(T[x],val); int mid=(l+r)>>1;
if (l==L && R==r) { F[x]=max(F[x],val); return; }
if (R<=mid)
Change(x<<1,l,mid,L,R,val);
else if (L>mid)
Change(x<<1|1,mid+1,r,L,R,val);
else
Change(x<<1,l,mid,L,mid,val),Change(x<<1|1,mid+1,r,mid+1,R,val);
}
int Max(int x,int l,int r,int L,int R){
int ret=F[x]; int mid=(l+r)>>1;
if (L==l && r==R) return T[x];
if (R<=mid)
ret=max(ret,Max(x<<1,l,mid,L,R));
else if (L>mid)
ret=max(ret,Max(x<<1|1,mid+1,r,L,R));
else
ret=max(ret,max(Max(x<<1,l,mid,L,mid),Max(x<<1|1,mid+1,r,mid+1,R)));
return ret;
}
};
struct SEGY{
SEGX T[N*3],F[N*3];
void Change(int x,int l,int r,int L,int R,int tl,int tr,int val){
T[x].Change(1,1,S,tl,tr,val); int mid=(l+r)>>1;
if (l==L && R==r) { F[x].Change(1,1,S,tl,tr,val); return; }
if (R<=mid)
Change(x<<1,l,mid,L,R,tl,tr,val);
else if (L>mid)
Change(x<<1|1,mid+1,r,L,R,tl,tr,val);
else
Change(x<<1,l,mid,L,mid,tl,tr,val),Change(x<<1|1,mid+1,r,mid+1,R,tl,tr,val);
}
int Max(int x,int l,int r,int L,int R,int tl,int tr){
int ret=F[x].Max(1,1,S,tl,tr); int mid=(l+r)>>1;
if (L==l && r==R) return T[x].Max(1,1,S,tl,tr);
if (R<=mid)
ret=max(ret,Max(x<<1,l,mid,L,R,tl,tr));
else if (L>mid)
ret=max(ret,Max(x<<1|1,mid+1,r,L,R,tl,tr));
else
ret=max(ret,max(Max(x<<1,l,mid,L,mid,tl,tr),Max(x<<1|1,mid+1,r,mid+1,R,tl,tr)));
return ret;
}
}SEG;
int main()
{
int x,y,d,s,h,tmp;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(D); read(S); read(Q);
while (Q--)
{
read(d); read(s); read(h); read(x); read(y);
tmp=SEG.Max(1,1,D,x+1,x+d,y+1,y+s)+h;
SEG.Change(1,1,D,x+1,x+d,y+1,y+s,tmp);
}
printf("%d\n",SEG.Max(1,1,D,1,D,1,S));
return 0;
}