zoukankan      html  css  js  c++  java
  • 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
    ",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
  • 相关阅读:
    (离线算法 LCA) hdu 2874
    (树形DP) hdu 4118
    (树的重心) poj 1655
    (线性基) bzoj 2115
    (线性基) bzoj 2460
    (边双联通+树直径) hdu 4612
    (拓扑图+DP) poj 3249
    (求割点和除去割点后的联通块数目) poj 1523
    (边双联通) poj 3352
    (DP求最长路) hdu 4607
  • 原文地址:https://www.cnblogs.com/radical/p/4149197.html
Copyright © 2011-2022 走看看