hdu--1542&&1255&1828--线段树<扫描线>
所谓扫描线一般按照习惯上 就是说从左到右 或者是 从下到上
这2题 都是这样的运用 但除此 也还有别的方法可以过
我们将下边标记为1 上边标记为-1 这是自下而上的扫描 如果是从左到右 那么自然是左边为1 右边为-1
这边 当然要进行离散化了。 因为是数据蛮大的浮点数嘛~
这步真的很重要= =
然后注意下 unique去重 或者自己手写for遍历一遍 我就懒的写了
直接Lower_bound就可以了 因为这些数据肯定能找到的嘛
这边 线段树的建树需要注意下 因为我们的叶子结点是 1-2 2-3这样的元线段 所以这边我们建立的不是通常我们所建立的1-1 2-2这样的。
其实我还是没有说到重点 就是对于该节点所表示的区间被覆盖一次 2次及以上 没覆盖 或者到达了叶子节点 我们究竟为什么是采取这些操作~
我们先来讲1542-求出矩形覆盖的所有面积<一个区域被覆盖2次 只计算一次>
艹。。。还是自己画图吧。。
但是有什么 不清楚的可以留言= =
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
1828 矩形周长并。。我觉得比上面2个难多了
这题的话 可以不使用 离散化了 因为都是 int数 而且范围不大 是从[-10000,10000]
我还是贴下离散化的好了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
just follow your heart