线段树矩形周长并
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 }