【二维线段树】poi2006 tet
2011-03-15 09:43
211 查看
题目大意
给你一个1000*1000的矩阵,支持两种操作:
1.查询一个子矩阵的最大值;
2.把一个子矩阵的值全部改为某一个值;
ps:矩阵内所有值递增;
一开始没有什么好idea,以前就想过关于二维线段树标记下放的问题,后来才明白了二维线段树在第一维上是不能下方标记的。
写了个很挫的四分树,TLE了。。
看了GHY的code才知道其实标记完全不需要下放,介于这道题的特殊性,标记具有了交换律和结合律,在第二维上维护两个线段树,一个关于标记的线段树,一个关于区间最大值的线段树即可。
h8oj RANK1:
给你一个1000*1000的矩阵,支持两种操作:
1.查询一个子矩阵的最大值;
2.把一个子矩阵的值全部改为某一个值;
ps:矩阵内所有值递增;
一开始没有什么好idea,以前就想过关于二维线段树标记下放的问题,后来才明白了二维线段树在第一维上是不能下方标记的。
写了个很挫的四分树,TLE了。。
program ex1; {$inline+} const mm=2100; var f,s:array[0..mm*mm] of longint; i,n,h,x1,y1,x2,y2,mh:longint; procedure find(i,l1,r1,l2,r2:longint);inline;var t,m1,m2:longint; begin if f[i]<=mh then exit; if (x1>l1)or(y1<r1)or(x2>l2)or(y2<r2) then begin t:=i<<2; m1:=(l1+r1)>>1;m2:=(l2+r2)>>1; if (x1<=m1)and(x2<=m2) then find(t,l1,m1,l2,m2); if (x1<=m1)and(y2>m2) then find(t+1,l1,m1,m2+1,r2); if (y1>m1)and(x2<=m2) then find(t+2,m1+1,r1,l2,m2); if (y1>m1)and(y2>m2) then find(t+3,m1+1,r1,m2+1,r2); if s[i]>mh then mh:=s[i]; end else if f[i]>mh then mh:=f[i]; end; procedure cover(i,l1,r1,l2,r2:longint);inline;var t,m1,m2:longint; begin if (x1>l1)or(y1<r1)or(x2>l2)or(y2<r2) then begin t:=i<<2; m1:=(l1+r1)>>1;m2:=(l2+r2)>>1; if (x1<=m1)and(x2<=m2) then cover(t,l1,m1,l2,m2); if (x1<=m1)and(y2>m2) then cover(t+1,l1,m1,m2+1,r2); if (y1>m1)and(x2<=m2) then cover(t+2,m1+1,r1,l2,m2); if (y1>m1)and(y2>m2) then cover(t+3,m1+1,r1,m2+1,r2); end else s[i]:=h; if h>f[i] then f[i]:=h; end; begin readln(n,n,n); for i:=1 to n do begin readln(y1,y2,h,x1,x2); inc(y1,x1);inc(y2,x2); inc(x1);inc(x2);mh:=0; find(1,1,1024,1,1024); inc(h,mh); cover(1,1,1024,1,1024); end; writeln(f[1]); end.
看了GHY的code才知道其实标记完全不需要下放,介于这道题的特殊性,标记具有了交换律和结合律,在第二维上维护两个线段树,一个关于标记的线段树,一个关于区间最大值的线段树即可。
h8oj RANK1:
program tet;{$inline+} type arr=array[0..2048,0..1] of longint; var f,s:array[0..2048] of arr; i,n,h,x1,y1,x2,y2,xx,yy,mh:longint; procedure find(i,l,r:longint;var f:arr);inline;var m,t:longint; begin if (x2>l)or(y2<r) then begin m:=(l+r)>>1;t:=i+i; if mh<f[i,1] then mh:=f[i,1]; if x2<=m then find(t,l,m,f); if m<y2 then find(t+1,m+1,r,f); end else if mh<f[i,0] then mh:=f[i,0]; end; procedure cover(i,l,r:longint;var f:arr);inline;var m,t:longint; begin if h>f[i,0] then f[i,0]:=h; if (x2>l)or(y2<r) then begin m:=(l+r)>>1;t:=i+i; if x2<=m then cover(t,l,m,f); if m<y2 then cover(t+1,m+1,r,f); end else if h>f[i,1] then f[i,1]:=h; end; procedure find(i,l,r:longint);inline;var m,t:longint; begin if (x1>l)or(y1<r) then begin m:=(l+r)>>1;t:=i+i; find(1,1,yy,s[i]); if x1<=m then find(t,l,m); if m<y1 then find(t+1,m+1,r); end else find(1,1,yy,f[i]); end; procedure cover(i,l,r:longint);inline;var m,t:longint; begin cover(1,1,yy,f[i]); if (x1>l)or(y1<r) then begin m:=(l+r)>>1;t:=i+i; if x1<=m then cover(t,l,m); if m<y1 then cover(t+1,m+1,r); end else cover(1,1,yy,s[i]); end; begin readln(xx,yy,n); for i:=1 to n do begin readln(y1,y2,h,x1,x2); inc(y1,x1);inc(y2,x2); inc(x1);inc(x2);mh:=0; find(1,1,xx); inc(h,mh); cover(1,1,xx); end; writeln(f[1,1,0]); end.
相关文章推荐
- [二维线段树] BZOJ 1513 [POI2006]Tet-Tetris 3D
- BZOJ 1513 POI2006 Tet-Tetris 3D 二维线段树
- 洛谷.3437.[POI2006]TET-Tetris 3D(二维线段树)
- BZOJ1513 [POI2006]Tet-Tetris 3D 【二维线段树】
- BZOJ1513: [POI2006]Tet-Tetris 3D 二维线段树
- 二维线段树 洛谷P3437 [POI2006]TET-Tetris 3D
- bzoj 1513: [POI2006]Tet-Tetris 3D 二维线段树
- bzoj1513 Tet-Tetris 3D(二维线段树)
- BZOJ 1513 [POI2006]Tet-Tetris 3D(二维线段树)
- bzoj 1513 [POI2006]Tet-Tetris 3D(二维线段树)
- 【BZOJ1513】[POI2006]Tet-Tetris 3D 二维线段树
- BZOJ 1513: [POI2006]Tet-Tetris 3D 二维线段树
- bzoj1513 [POI2006]Tet-Tetris 3D(二维线段树)
- BZOJ 1513 [POI2006]Tet-Tetris 3D 二维线段树
- BZOJ1513 [POI2006]Tet-Tetris 3D 二维线段树
- BZOJ 1513 POI 2006 Tet-Tetris 3D 二维线段树
- HDU 4819 Mosaic(二维线段树+单点更新)
- Yet Another Tree Query Problem(二维线段树)
- 二维线段树之降维打击
- HDU 4819 Mosaic(二维线段树)