题意:给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
分析:这题跟poj 1151有点相似,只不过多了至少覆盖两次而已。那我们就在原来的基础上改进一下。
一开始的操作,像离散化之类的基本相同,然后在线段树的插入操作中,我们给每个节点新定义了一个值,表示该节点的三种状态:被覆盖了一部分、全部被覆盖和还没被覆盖,然后分情况进行处理,具体方法请看代码,再把被覆盖了两次的加入原来的统计扫描线上边的长度的变量中去,最后统计结果就好啦。
还不懂的就来理解一下代码吧。
代码:
var o,l,n,a1,i:longint; x1,x2,y1,y2,s,ans:real; t:array[1..5000,1..4] of longint; a:array[0..3000] of real; bian:array[0..3000,1..3] of real; b:array[0..3000] of longint; procedure sort1; var i,j:longint; begin for i:=1 to n*2-1 do for j:=i+1 to n*2 do if bian[i,1]>bian[j,1] then begin bian[0]:=bian[i];bian[i]:=bian[j];bian[j]:=bian[0]; b[0]:=b[i];b[i]:=b[j];b[j]:=b[0]; end; end; procedure sort2; var i,j:longint; begin for i:=1 to n*2-1 do for j:=i+1 to n*2 do if a[i]>a[j] then begin a[0]:=a[i];a[i]:=a[j];a[j]:=a[0]; end; end; procedure hehe(d,l,r:longint); var m:longint; begin t[d,1]:=l; t[d,2]:=r; t[d,3]:=0; t[d,4]:=0; if r-l=1 then exit; m:=(l+r) div 2; hehe(d*2,l,m); hehe(d*2+1,m,r); end; procedure insert(d:longint;l,r:real;z:longint); var m:longint; begin m:=(t[d,1]+t[d,2]) div 2; if (a[t[d,1]]=l)and(a[t[d,2]]=r) then begin if t[d,4]=0 then begin t[d,4]:=2; t[d,3]:=t[d,3]+z; if t[d,3]=z*2 then s:=s+r-l; if t[d,3]=-z then s:=s-r+l; end else if t[d,4]=1 then begin insert(d*2,l,a[m],z); insert(d*2+1,a[m],r,z); end else begin t[d,3]:=t[d,3]+z; if t[d,3]=z*2 then s:=s+r-l; if t[d,3]=-z then s:=s-r+l; end; exit; end; if t[d,4]=2 then begin t[d*2,4]:=2; t[d*2+1,4]:=2; t[d*2,3]:=t[d*2,3]+t[d,3]; t[d*2+1,3]:=t[d*2+1,3]+t[d,3]; end; t[d,4]:=1; if r<=a[m] then insert(d*2,l,r,z) else if l>=a[m] then insert(d*2+1,l,r,z) else begin insert(d*2,l,a[m],z); insert(d*2+1,a[m],r,z); end; end; begin readln(o); for l:=1 to o do begin readln(n); for i:=1 to n do begin readln(x1,y1,x2,y2); bian[i*2-1,1]:=y1; bian[i*2-1,2]:=x1; bian[i*2-1,3]:=x2; b[i*2-1]:=1; bian[i*2,1]:=y2; bian[i*2,2]:=x1; bian[i*2,3]:=x2; b[i*2]:=-1; a[i*2-1]:=x1; a[i*2]:=x2; end; sort1; sort2; a1:=n*2; for i:=1 to n*2-1 do if a[i]=a[i+1] then begin a[i]:=maxlongint div 10; dec(a1); end; sort2; hehe(1,1,a1); i:=1; bian[0,1]:=-1; bian[n*2+1,1]:=-1; s:=0; ans:=0; while i<=n*2 do begin insert(1,bian[i,2],bian[i,3],b[i]); while bian[i,1]=bian[i+1,1] do begin inc(i); insert(1,bian[i,2],bian[i,3],b[i]); end; ans:=ans+s*(bian[i+1,1]-bian[i,1]); inc(i); end; writeln(ans:0:2); end; end.