HDU 1828 Picture

线段树矩形周长并

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 
  6 #define lson l, m, rt << 1
  7 #define rson m + 1, r, rt << 1 | 1
  8 
  9 using namespace std;
 10 
 11 struct Seg_Tree
 12 {
 13     int l, r, h, s;
 14     Seg_Tree() {}
 15     Seg_Tree( int a, int b, int c, int d ):l(a), r(b), h(c), s(d) { }
 16     bool operator<( const Seg_Tree &rhs ) const
 17     {
 18         if ( h == rhs.h ) return s > rhs.s;
 19         return h < rhs.h;
 20     }
 21 };
 22 
 23 const int MAXN = 5004 << 2;
 24 const int INF = 1 << 30;
 25 
 26 Seg_Tree R[MAXN];
 27 int cnt[MAXN << 2 ];
 28 int segnum[MAXN << 2];
 29 int len[MAXN << 2];
 30 bool lbd[MAXN << 2], rbd[MAXN << 2];
 31 
 32 void PushUp( int rt, int l, int r )
 33 {
 34     int lc = rt << 1;
 35     int rc = rt << 1 | 1;
 36     if ( cnt[rt] )
 37     {
 38         lbd[rt] = rbd[rt] = true;
 39         len[rt] = r - l + 1;
 40         segnum[rt] = 2;
 41     }
 42     else if ( l == r )
 43     {
 44         len[rt] = segnum[rt] = 0;
 45         lbd[rt] = rbd[rt] = false;
 46     }
 47     else
 48     {
 49         lbd[rt] = lbd[lc];
 50         rbd[rt] = rbd[rc];
 51         len[rt] = len[lc] + len[rc];
 52         segnum[rt] = segnum[lc] + segnum[rc];
 53         if ( rbd[lc] && lbd[rc] ) segnum[rt] -= 2;
 54     }
 55     return;
 56 }
 57 
 58 void Update( int L, int R, int c, int l, int r, int rt )
 59 {
 60     if ( L <= l && r <= R )
 61     {
 62         cnt[rt] += c;
 63         PushUp( rt, l, r );
 64         return;
 65     }
 66 
 67     int m = ( l + r ) >> 1;
 68     if ( L <= m ) Update( L, R, c, lson );
 69     if ( R > m ) Update( L, R, c, rson );
 70     PushUp( rt, l, r );
 71     return;
 72 }
 73 
 74 int main()
 75 {
 76     int N;
 77     while ( ~scanf( "%d", &N ) )
 78     {
 79         int m = 0;
 80         int low = INF, high = -INF;
 81         for ( int i = 0; i < N; ++i )
 82         {
 83             int a, b, c, d;
 84             scanf( "%d%d%d%d", &a, &b, &c, &d );
 85             low = min( low, a );
 86             high = max( high, c );
 87             R[ m++ ] = Seg_Tree( a, c, b, 1 );
 88             R[ m++ ] = Seg_Tree( a, c, d, -1 );
 89         }
 90 
 91         sort( R, R + m );
 92 
 93         int ans = 0, last = 0;
 94         for ( int i = 0; i < m; ++i )
 95         {
 96             if ( R[i].l < R[i].r ) Update( R[i].l, R[i].r - 1, R[i].s, low, high - 1, 1 );
 97             ans += segnum[1] * ( R[i + 1].h - R[i].h );
 98             ans += abs( len[1] - last );
 99             last = len[1];
100         }
101         printf( "%d\n", ans );
102     }
103     return 0;
104 }
原文地址:https://www.cnblogs.com/GBRgbr/p/3068838.html