题意:每次把坐标系上的一个矩形内的权值修改成矩形内最大权值+w。求最后最大权值。
二维线段树,但外层数据结构既不能pushup(总不能重构内层树吧?),也不能pushdown(两个标记不能相加)。
我草,那怎么办?
标记永久化,打两种标记,第一种标记对经过的每一个点一路打下来,查询时精确查找。第二种标记恰好相反。
那么对于查找的区间在标记区间之上的情况会查到第一种标记,在标记之下的情况会查到第二种标记。
话说我以前似乎说过树套树外层不支持区间修改? flag秒收呀。。。
#include <bits/stdc++.h>
using namespace std;
#define N 3007
#define ls l,mid,now<<1
#define rs mid+1,r,now<<1|1
int D,S,n,ans;
int X1,Y1,X2,Y2;
struct tree2
{
int b1[N],b2[N];
int query(int l,int r,int now)
{
if(Y1<=l&&r<=Y2)return b1[now];
int mid=(l+r)>>1,ret=b2[now];
if(mid>=Y1)ret=max(ret,query(ls));
if(mid<Y2) ret=max(ret,query(rs));
return ret;
}
void update(int l,int r,int now,int v)
{
b1[now]=max(b1[now],v);
if(Y1<=l&&r<=Y2)
{b2[now]=max(b2[now],v);return;}
int mid=(l+r)>>1;
if(mid>=Y1)update(ls,v);
if(mid<Y2) update(rs,v);
}
};
struct tree1
{
tree2 b1[N],b2[N];
int query(int l,int r,int now)
{
if(X1<=l&&r<=X2)
return b1[now].query(1,S,1);
int mid=(l+r)>>1,ret=b2[now].query(1,S,1);
if(mid>=X1)ret=max(ret,query(ls));
if(mid<X2) ret=max(ret,query(rs));
return ret;
}
void update(int l,int r,int now,int v)
{
b1[now].update(1,S,1,v);
if(X1<=l&&r<=X2)
{b2[now].update(1,S,1,v);return;}
int mid=(l+r)>>1;
if(mid>=X1)update(ls,v);
if(mid<X2) update(rs,v);
}
}tr1;
int main()
{
//freopen("tt.in","r",stdin);
scanf("%d%d%d",&D,&S,&n);
for(int i=1,d,s,w,x,y;i<=n;i++)
{
scanf("%d%d%d%d%d",&d,&s,&w,&x,&y);
x++;y++;X1=x;Y1=y;X2=x+d-1;Y2=y+s-1;
int t=tr1.query(1,D,1);
tr1.update(1,D,1,t+w);
ans=max(ans,t+w);
}
printf("%d\n",ans);
return 0;
}