POJ1151+线段树+扫描线
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 线段树+扫描线+离散化 3 求多个矩形的面积 4 */ 5 #include<stdio.h> 6 #include<string.h> 7 #include<stdlib.h> 8 #include<algorithm> 9 #include<iostream> 10 #include<queue> 11 #include<stack> 12 #include<math.h> 13 #include<map> 14 using namespace std; 15 const int maxn = 105; 16 const int maxm = 210; 17 struct SegTree{ 18 int l,r; 19 int cover; 20 double L_val,R_val; 21 double sum; 22 }ST[ maxm<<2 ]; 23 struct Line{ 24 double x,y1,y2; 25 bool InOut; 26 }yLine[ maxm ]; 27 int cmp( Line a,Line b ){ 28 return a.x<b.x; 29 } 30 double yIndex[ maxm ]; 31 int GetIndex( double val,int cnt ){ 32 return lower_bound( yIndex,yIndex+cnt,val )-yIndex; 33 } 34 35 void build( int L,int R,int n ){ 36 ST[ n ].l = L; 37 ST[ n ].r = R; 38 ST[ n ].cover = 0; 39 ST[ n ].sum = 0; 40 ST[ n ].L_val = yIndex[ L ]; 41 ST[ n ].R_val = yIndex[ R ]; 42 if( R-L>1 ){ 43 int mid = (L+R)/2; 44 build( L,mid,2*n ); 45 build( mid,R,2*n+1 ); 46 } 47 } 48 void PushUp( int n ){ 49 if( ST[ n ].cover>0 ){ 50 ST[ n ].sum = ST[ n ].R_val-ST[ n ].L_val; 51 } 52 else if( ST[ n ].r-ST[ n ].l>1 ){ 53 ST[ n ].sum = ST[ 2*n ].sum+ST[ 2*n+1 ].sum; 54 } 55 else 56 ST[ n ].sum = 0; 57 } 58 void update( int left,int right,bool InOut,int n ){ 59 if( left==ST[ n ].l&&right==ST[ n ].r ){ 60 if( InOut==true ){ 61 ST[ n ].cover++; 62 } 63 else{ 64 ST[ n ].cover--; 65 } 66 } 67 else { 68 int mid = (ST[ n ].l+ST[ n ].r)/2; 69 if( mid>=right ) update( left,right,InOut,2*n ); 70 else if( mid<=left ) update( left,right,InOut,2*n+1 ); 71 else { 72 update( left,mid,InOut,2*n ); 73 update( mid,right,InOut,2*n+1 ); 74 } 75 } 76 PushUp( n ); 77 } 78 79 int main(){ 80 int n; 81 int T = 1; 82 while( scanf("%d",&n)==1,n ){ 83 printf("Test case #%d\n",T++); 84 double x1,y1,x2,y2; 85 int cnt = 0; 86 for( int i=0;i<n;i++ ){ 87 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 88 yLine[ 2*i ].x = x1; 89 yLine[ 2*i+1 ].x = x2; 90 yLine[ 2*i ].y1 = yLine[ 2*i+1 ].y1 = y1; 91 yLine[ 2*i ].y2 = yLine[ 2*i+1 ].y2 = y2; 92 yLine[ 2*i ].InOut = true; 93 yLine[ 2*i+1 ].InOut = false; 94 yIndex[ 2*i ] = y1; 95 yIndex[ 2*i+1 ] = y2; 96 } 97 sort( yLine,yLine+2*n,cmp ); 98 sort( yIndex,yIndex+2*n ); 99 for( int i=1;i<2*n;i++ ){ 100 if( yIndex[i]!=yIndex[i-1] ) 101 yIndex[ cnt++ ] = yIndex[ i-1 ]; 102 } 103 yIndex[ cnt++ ] = yIndex[ 2*n-1 ]; 104 build( 0,cnt-1,1 ); 105 double res = 0; 106 update( GetIndex( yLine[0].y1,cnt ),GetIndex( yLine[0].y2,cnt ),yLine[0].InOut,1 ); 107 for( int i=1;i<2*n;i++ ){ 108 res += ST[ 1 ].sum*( yLine[i].x-yLine[i-1].x ); 109 update( GetIndex( yLine[i].y1,cnt ),GetIndex( yLine[i].y2,cnt ),yLine[i].InOut,1 ); 110 } 111 printf("Total explored area: %.2lf\n\n",res); 112 } 113 return 0; 114 }
keep moving...