写一个数据结构,支持查询一个矩形的最大值 并将这个矩形的值全部变为 这个最大值加一个常数
二维线段树+标记永久化
maxi表示子树内的一个最大值,tag表示子树全部都被覆盖的值…
Luogu 3437
#include
#include
#include
#include
int Maxx,Maxy,n;
struct inside_seg{
int maxi[4005],tag[4005];
void modify(int o,int l,int r,int ql,int qr,int k)
{
maxi[o]=std::max(maxi[o],k);
if(ql<=l&&r<=qr) return (void)(tag[o]=std::max(tag[o],k));
int mid=(l+r)>>1;
if(ql<=mid) modify((o<<1),l,mid,ql,qr,k);
if(qr>mid) modify((o<<1)|1,mid+1,r,ql,qr,k);
}
int ask(int o,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr) return std::max(tag[o],maxi[o]);
int mid=(l+r)>>1;
int ans=tag[o];
if(ql<=mid) ans=std::max(ans,ask((o<<1),l,mid,ql,qr));
if(qr>mid) ans=std::max(ans,ask((o<<1)|1,mid+1,r,ql,qr));
return ans;
}
};
struct external_seg{
inside_seg maxi[4005],tag[4005];
void modify(int o,int l,int r,int ql,int qr,int y1,int y2,int k)
{
maxi[o].modify(1,0,Maxy,y1,y2,k);
if(ql<=l&&r<=qr) return (void)(tag[o].modify(1,0,Maxy,y1,y2,k));
int mid=(l+r)>>1;
if(ql<=mid) modify((o<<1),l,mid,ql,qr,y1,y2,k);
if(qr>mid) modify((o<<1)|1,mid+1,r,ql,qr,y1,y2,k);
}
int ask(int o,int l,int r,int ql,int qr,int y1,int y2)
{
if(ql<=l&&r<=qr) return maxi[o].ask(1,0,Maxy,y1,y2);
int mid=(l+r)>>1;
int ans=tag[o].ask(1,0,Maxy,y1,y2);
if(ql<=mid) ans=std::max(ans,ask((o<<1),l,mid,ql,qr,y1,y2));
if(qr>mid) ans=std::max(ans,ask((o<<1)|1,mid+1,r,ql,qr,y1,y2));
return ans;
}
}T;
int main()
{
scanf("%d%d%d",&Maxx,&Maxy,&n);
for(int i=1,d,s,h,x,y;i<=n;i++)
{
scanf("%d%d%d%d%d",&d,&s,&h,&x,&y);
h+=T.ask(1,0,Maxx,x,x+d-1,y,y+s-1);
T.modify(1,0,Maxx,x,x+d-1,y,y+s-1,h);
}
printf("%d\n",T.ask(1,0,Maxx,0,Maxx,0,Maxy));
return 0;
}