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 }

你可能感兴趣的:(HDU)