POJ1151+线段树+扫描线

  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 }
View Code

 

你可能感兴趣的:(poj)