码迷,mamicode.com
首页 > 其他好文 > 详细

hdu--1542&&1255--线段树<扫描线>

时间:2014-12-07 12:29:07      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   sp   for   

所谓扫描线一般按照习惯上 就是说从左到右 或者是 从下到上 

这2题 都是这样的运用 但除此 也还有别的方法可以过

我们将下边标记为1 上边标记为-1  这是自下而上的扫描   如果是从左到右 那么自然是左边为1 右边为-1

这边 当然要进行离散化了。  因为是数据蛮大的浮点数嘛~

这步真的很重要= =

然后注意下 unique去重 或者自己手写for遍历一遍 我就懒的写了

直接Lower_bound就可以了  因为这些数据肯定能找到的嘛

这边 线段树的建树需要注意下  因为我们的叶子结点是 1-2    2-3这样的元线段 所以这边我们建立的不是通常我们所建立的1-1  2-2这样的。

其实我还是没有说到重点 就是对于该节点所表示的区间被覆盖一次 2次及以上 没覆盖 或者到达了叶子节点 我们究竟为什么是采取这些操作~

我们先来讲1542-求出矩形覆盖的所有面积<一个区域被覆盖2次 只计算一次>

艹。。。还是自己画图吧。。

但是有什么 不清楚的可以留言= =    

 

bubuko.com,布布扣
  1 #include <iostream>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iomanip>
  5 using namespace std;
  6 
  7 int cnt;
  8 const int size = 220;
  9 struct data
 10 {
 11     int L , R;
 12     double x1 , x2 , y;
 13     double sum;
 14     int flag;
 15     data(){};
 16     data( double u , double v , double w , int p ):x1(u),x2(v),y(w),flag(p){};
 17 }tree[size*4] , mat[size];
 18 double w[size];
 19 
 20 bool cmp( const data p , const data q )
 21 {
 22     return p.y < q.y;
 23 }
 24 
 25 void pushUp( int rt )
 26 {
 27     if( tree[rt].flag )
 28         tree[rt].sum = w[ tree[rt].R ] - w[ tree[rt].L ];
 29     else if( tree[rt].L+1==tree[rt].R )
 30         tree[rt].sum = 0;
 31     else
 32         tree[rt].sum =  tree[rt<<1].sum + tree[rt<<1|1].sum;
 33 }
 34 
 35 void build( int rt , int L , int R )
 36 {
 37     int M = ( L + R ) >> 1;
 38     tree[rt].L = L;
 39     tree[rt].R = R;
 40     tree[rt].sum = 0;
 41     tree[rt].flag = 0;
 42     if( L+1==R )
 43     {
 44         return ;
 45     }
 46     build( rt<<1 , L , M );
 47     build( rt<<1|1 , M , R );
 48 }
 49 
 50 void update( int rt , int L , int R , int var )//var区别是上边还是下边
 51 {
 52     int M = ( tree[rt].L + tree[rt].R ) >> 1;
 53     if( tree[rt].L == L && tree[rt].R == R )
 54     {
 55         tree[rt].flag += var;
 56         pushUp( rt );
 57         return ;
 58     }
 59     if( R<=M )
 60         update( rt<<1 , L , R , var );
 61     else if( L>=M )
 62         update( rt<<1|1 , L , R , var );
 63     else
 64     {
 65         update( rt<<1 , L , M , var );
 66         update( rt<<1|1 , M , R , var );
 67     }
 68     pushUp( rt );
 69 }
 70 
 71 int main()
 72 {
 73     int Case = 1 , n;
 74     double x1 , y1 , x2 , y2;
 75     double ans;
 76     while( cin >> n && n )
 77     {
 78         cnt = 1;
 79         for( int i = 0 ; i<n ; i++ )
 80         {
 81             cin >> x1 >> y1 >> x2 >> y2;
 82             w[cnt] = x1;
 83             mat[cnt++] = data( x1 , x2 , y1 , 1 );
 84             w[cnt] = x2;
 85             mat[cnt++] = data( x1 , x2 , y2 , -1 );
 86         }
 87         sort( w+1 , w+cnt );//离散化x轴坐标 
 88         sort( mat+1 , mat+cnt , cmp );//按y的高低来排 
 89         cnt = unique( w+1 , w+cnt ) - w;
 90         build( 1 , 1 , cnt-1 );
 91         ans = 0;
 92         for( int i = 1 ; i<(n<<1) ; i++ )
 93         {
 94             int L = lower_bound( w+1 , w+cnt , mat[i].x1 ) - w;
 95             int R = lower_bound( w+1 , w+cnt , mat[i].x2 ) - w;    
 96             update( 1 , L , R , mat[i].flag );
 97             ans += tree[1].sum * ( mat[i+1].y - mat[i].y );
 98         }
 99         cout << "Test case #" << Case++ << endl;
100         cout << "Total explored area: ";
101         cout << setiosflags(ios::fixed);
102         cout << setprecision(2) << ans << endl << endl;
103     }
104     return 0;
105 }
View Code
bubuko.com,布布扣
  1 #include <iostream>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iomanip>
  5 using namespace std;
  6 
  7 int cnt;
  8 const int size = 2200;
  9 struct data
 10 {
 11     int L , R;
 12     double x1 , x2 , y;
 13     double onceSum;
 14     double twiceSum;
 15     int flag;
 16     data(){};
 17     data( double u , double v , double w , int p ):x1(u),x2(v),y(w),flag(p){};
 18 }tree[size*4] , mat[size];
 19 double w[size];
 20 
 21 bool cmp( const data p , const data q )
 22 {
 23     return p.y < q.y;
 24 }
 25 
 26 void push( int rt )
 27 {
 28     if( tree[rt].flag )
 29         tree[rt].onceSum = w[ tree[rt].R ] - w[ tree[rt].L ];
 30     else if( tree[rt].L +1 == tree[rt].R )
 31         tree[rt].onceSum = 0;
 32     else
 33         tree[rt].onceSum = tree[rt<<1].onceSum + tree[rt<<1|1].onceSum;
 34 }
 35 
 36 void pushUp( int rt )
 37 {
 38     if( tree[rt].flag>=2 )
 39         tree[rt].twiceSum = w[ tree[rt].R ] - w[ tree[rt].L ];
 40     else if( tree[rt].L +1 == tree[rt].R )
 41         tree[rt].twiceSum = 0;
 42     else if( tree[rt].flag==1 )
 43         tree[rt].twiceSum = tree[rt<<1].onceSum + tree[rt<<1|1].onceSum;
 44     else
 45         tree[rt].twiceSum =  tree[rt<<1].twiceSum + tree[rt<<1|1].twiceSum;
 46 }
 47 
 48 void build( int rt , int L , int R )
 49 {
 50     int M = ( L + R ) >> 1;
 51     tree[rt].L = L;
 52     tree[rt].R = R;
 53     tree[rt].onceSum = tree[rt].twiceSum = 0;
 54     tree[rt].flag = 0;
 55     if( L+1==R )
 56     {
 57         return ;
 58     }
 59     build( rt<<1 , L , M );
 60     build( rt<<1|1 , M , R );
 61 }
 62 
 63 void update( int rt , int L , int R , int var )//var区别是上边还是下边
 64 {
 65     int M = ( tree[rt].L + tree[rt].R ) >> 1;
 66     if( tree[rt].L == L && tree[rt].R == R )
 67     {
 68         tree[rt].flag += var;
 69         push( rt );
 70         pushUp( rt );
 71         return ;
 72     }
 73     if( R<=M )
 74         update( rt<<1 , L , R , var );
 75     else if( L>=M )
 76         update( rt<<1|1 , L , R , var );
 77     else
 78     {
 79         update( rt<<1 , L , M , var );
 80         update( rt<<1|1 , M , R , var );
 81     }
 82     push( rt );
 83     pushUp( rt );
 84 }
 85 
 86 int main()
 87 {
 88     int n , T;
 89     double x1 , y1 , x2 , y2;
 90     double ans;
 91     while( ~scanf("%d",&T) )
 92     {
 93         while( T-- )
 94         {
 95             cnt = 1;
 96             scanf("%d",&n);
 97             for( int i = 0 ; i<n ; i++ )
 98             {
 99                 scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
100                 w[cnt] = x1;
101                 mat[cnt++] = data( x1 , x2 , y1 , 1 );
102                 w[cnt] = x2;
103                 mat[cnt++] = data( x1 , x2 , y2 , -1 );
104             }
105             sort( w+1 , w+cnt );//离散化x轴坐标 
106             sort( mat+1 , mat+cnt , cmp );//按y的高低来排 
107             cnt = unique( w+1 , w+cnt ) - w;
108             build( 1 , 1 , cnt-1 );
109             ans = 0;
110             for( int i = 1 ; i<(n<<1) ; i++ )
111             {
112                 int L = lower_bound( w+1 , w+cnt , mat[i].x1 ) - w;
113                 int R = lower_bound( w+1 , w+cnt , mat[i].x2 ) - w;    
114                 update( 1 , L , R , mat[i].flag );
115                 ans += tree[1].twiceSum * ( mat[i+1].y - mat[i].y );
116             }
117             //cout << setiosflags(ios::fixed);
118             //cout << setprecision(2) << ans << endl;
119             printf("%.2lf\n",ans);
120         }
121     }
122     return 0;
123 }
View Code

 

hdu--1542&&1255--线段树<扫描线>

标签:style   blog   http   io   ar   color   os   sp   for   

原文地址:http://www.cnblogs.com/radical/p/4149197.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!