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

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

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

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

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

这步真的很重要= =

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

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

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

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

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

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

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

 

  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
  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

 1828  矩形周长并。。我觉得比上面2个难多了

这题的话 可以不使用 离散化了 因为都是 int数 而且范围不大 是从[-10000,10000]

我还是贴下离散化的好了 

  1 #include <iostream>
  2 #include <algorithm>
  3 using namespace std;
  4 
  5 const int size = 5020;
  6 int cnt;
  7 struct data
  8 {
  9     int x1 , x2 , x , y , L , R;
 10     int flag , sum , num;
 11     bool Lflag , Rflag;
 12     data(){};
 13     data( int u , int v , int w , int p ):x1(u),x2(v),y(w),flag(p){};
 14     
 15 }tree[size<<2] , mat[size*2];
 16 int w[size*2];
 17 
 18 int Abs( int x )
 19 {
 20     return x > 0 ? x : -x;
 21 }
 22 
 23 bool cmp( const data p , const data q )
 24 {
 25     return p.y < q.y;
 26 }
 27 
 28 void pushUp( int rt )
 29 {
 30     if( tree[rt].flag )
 31     {
 32         tree[rt].sum = w[ tree[rt].R ] - w[ tree[rt].L ];
 33         tree[rt].Lflag = tree[rt].Rflag = 1;
 34         tree[rt].num = 1;
 35     }
 36     else if( tree[rt].L +1 ==tree[rt].R )
 37     {
 38         tree[rt].sum = tree[rt].num = 0;
 39         tree[rt].Lflag = tree[rt].Rflag = 0;
 40     }
 41     else
 42     {
 43         tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
 44         tree[rt].Lflag = tree[rt<<1].Lflag;
 45         tree[rt].Rflag = tree[rt<<1|1].Rflag;
 46         tree[rt].num = tree[rt<<1].num + tree[rt<<1|1].num- tree[rt<<1].Rflag*tree[rt<<1|1].Lflag;
 47     }
 48 }
 49                                     
 50 void build( int rt , int L , int R )
 51 {
 52     int M = (L+R) >> 1;
 53     tree[rt].L = L;
 54     tree[rt].R = R;
 55     tree[rt].flag = tree[rt].sum = tree[rt].num = 0;
 56     tree[rt].Lflag = tree[rt].Rflag = 0;
 57     if( L+1 == R )
 58     {
 59         return ;
 60     }
 61     build( rt<<1 , L , M );
 62     build( rt<<1|1 , M , R );
 63 }
 64 
 65 void update( int rt , int L , int R , int var )
 66 {
 67     int M = ( tree[rt].L + tree[rt].R ) >> 1;
 68     if( tree[rt].L == L && tree[rt].R == R )
 69     {
 70         tree[rt].flag += var;
 71         pushUp( rt );
 72         return ;
 73     }
 74     if( R<=M )
 75         update( rt<<1 , L , R , var );
 76     else if( L>=M )
 77         update( rt<<1|1 , L , R , var );
 78     else
 79     {
 80         update( rt<<1 , L , M , var );
 81         update( rt<<1|1 , M , R , var );
 82     }
 83     pushUp( rt );
 84 }
 85 
 86 int main()
 87 {
 88     cin.sync_with_stdio(false);
 89     int n , pre , ans , L , R;
 90     int x1 , x2 , y1 , y2;
 91     while( cin >> n )
 92     {
 93         cnt = 1;
 94         for( int i = 0 ; i<n ; i++ )
 95         {
 96             cin >> x1 >> y1 >> x2 >> y2;
 97             w[cnt] = x1;
 98             mat[cnt++] = data( x1 , x2 , y1 , 1 );
 99             w[cnt] = x2;
100             mat[cnt++] = data( x1 , x2 , y2 , -1 );
101         }
102         sort( w+1 , w+cnt );
103         sort( mat+1 , mat+cnt , cmp );
104         cnt = unique( w+1 , w+cnt ) - w;
105         build( 1 , 1 , cnt-1 );
106         ans = pre = 0;
107         for( int i = 1 ; i<(n<<1); i++ )
108         {
109             L = lower_bound( w+1 , w+cnt , mat[i].x1 ) - w;
110             R = lower_bound( w+1 , w+cnt , mat[i].x2 ) - w;
111             update( 1 , L , R , mat[i].flag );
112             ans += Abs( tree[1].sum - pre );
113             pre = tree[1].sum;
114             ans += tree[1].num * ( mat[i+1].y - mat[i].y ) * 2;
115         }
116         ans += mat[n<<1].x2 - mat[n<<1].x1;
117         cout << ans << endl;
118     }
119     return 0;
120 }
View Code

 

posted @ 2014-12-07 11:12  radical  阅读(144)  评论(0编辑  收藏  举报