标签:ace 最大 input pushd log 更新 soft char ons
题解:还是给一个直来直去的题面吧:给你一个平面,每次将一个矩形中的所有数改为(矩形中的最大数+w),问n次操作后平面内最大的数是多少。
看题面就知道一定是要用二维线段树的,不过二维线段树必须标记永久化。标记永久化这个词对本蒟蒻来说倒是比较陌生,不过仔细想想以前也的确做过许多用到标记永久化的思想的题。
说白了,就是在区间更新和区间查询的时候,免去pushup和pushdown操作,而是改为:更新的时候,修改沿路的所有pushup的标记,并修改目标节点的pushdown标记;查询的时候,查询沿路的所有pushdown标记,并查询目标节点的pushup标记。
哦,对了,必须标记永久化 说的是外层线段树,内层线段树还是可以正常搞的。
此外本题略微卡空间~
#include <cstdio> #include <cstring> #include <iostream> #define lson x<<1 #define rson x<<1|1 using namespace std; const int maxn=1010; int n,D,S; int rup[maxn<<2],rdn[maxn<<2]; struct sag { int sm[maxn<<12],tag[maxn<<12],ls[maxn<<12],rs[maxn<<12],tot; void pushdown(int x) { if(tag[x]) { if(!ls[x]) ls[x]=++tot; if(!rs[x]) rs[x]=++tot; sm[ls[x]]=max(sm[ls[x]],tag[x]),tag[ls[x]]=max(tag[ls[x]],tag[x]); sm[rs[x]]=max(sm[rs[x]],tag[x]),tag[rs[x]]=max(tag[rs[x]],tag[x]); tag[x]=0; } } void updata(int l,int r,int &x,int a,int b,int c) { if(!x) x=++tot; if(a<=l&&r<=b) { sm[x]=max(sm[x],c),tag[x]=max(tag[x],c); return ; } pushdown(x); int mid=l+r>>1; if(a<=mid) updata(l,mid,ls[x],a,b,c); if(b>mid) updata(mid+1,r,rs[x],a,b,c); sm[x]=max(sm[ls[x]],sm[rs[x]]); } int query(int l,int r,int x,int a,int b) { if(!x) return 0; if(a<=l&&r<=b) return sm[x]; pushdown(x); int mid=l+r>>1; if(b<=mid) return query(l,mid,ls[x],a,b); if(a>mid) return query(mid+1,r,rs[x],a,b); return max(query(l,mid,ls[x],a,b),query(mid+1,r,rs[x],a,b)); } }sup,sdn; void modify(int l,int r,int x,int a,int b,int c,int d,int e) { sup.updata(1,S,rup[x],c,d,e); if(a<=l&&r<=b) { sdn.updata(1,S,rdn[x],c,d,e); return ; } int mid=l+r>>1; if(a<=mid) modify(l,mid,lson,a,b,c,d,e); if(b>mid) modify(mid+1,r,rson,a,b,c,d,e); } int ask(int l,int r,int x,int a,int b,int c,int d) { int mid=l+r>>1,ret=sdn.query(1,S,rdn[x],c,d); if(a<=l&&r<=b) ret=max(ret,sup.query(1,S,rup[x],c,d)); else { if(a<=mid) ret=max(ret,ask(l,mid,lson,a,b,c,d)); if(b>mid) ret=max(ret,ask(mid+1,r,rson,a,b,c,d)); } return ret; } int rd() { int ret=0,f=1; char gc=getchar(); while(gc<‘0‘||gc>‘9‘) {if(gc==‘-‘)f=-f; gc=getchar();} while(gc>=‘0‘&&gc<=‘9‘) ret=ret*10+gc-‘0‘,gc=getchar(); return ret*f; } int main() { D=rd(),S=rd(),n=rd(); int i,j,a,b,c,d,e; for(i=1;i<=n;i++) { c=rd(),d=rd(),e=rd(),a=rd(),b=rd(); modify(1,D,1,a+1,a+c,b+1,b+d,ask(1,D,1,a+1,a+c,b+1,b+d)+e); } printf("%d",ask(1,D,1,1,D,1,S)); return 0; }
【BZOJ1513】[POI2006]Tet-Tetris 3D 二维线段树
标签:ace 最大 input pushd log 更新 soft char ons
原文地址:http://www.cnblogs.com/CQzhangyu/p/7078857.html