hdu 1542 Atlantis (线段树+扫描线)

http://acm.hdu.edu.cn/showproblem.php?pid=1542

单纯的线段树+扫描线求面积并,需要离散化。

code:

#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include < string>
#include <iostream>
#include <sstream>
#include < set>
#include <queue>
#include <stack>
#include <fstream>
#include <iomanip>
#include <bitset>
#include <list>
#include <ctime>
using  namespace std ;

#define SET(arr, what)  memset(arr, what, sizeof(arr))
#define FF(i, a)        for(i=0; i<a; i++)
#define SD(a)           scanf("%d", &a)
#define SSD(a, b)       scanf("%d%d", &a, &b)
#define SSF(a, b)       scanf("%lf%lf", &a, &b)
#define SS(a)           scanf("%s", a)
#define SLD(a)          scanf("%lld", &a)
#define PF(a)           printf("%d\n", a)
#define PPF(a, b)       printf("%d %d\n", a, b)
#define PLF(a)          printf("%lf\n", a)
#define SZ(arr)         (int)a.size()
#define SWAP(a,b)       a=a xor b;b= a xor b;a=a xor b;
#define read            freopen("in.txt", "r", stdin)
#define write            freopen("out.txt", "w", stdout)
#define MAX             1<<30
#define ESP             1e-5
#define lson            l, m, rt<<1
#define rson            m+1, r, rt<<1|1
template< class T> inline T sqr(T a){ return a*a;}
template< class T> inline  void AMin(T &a,T b){ if(a==- 1||a>b)a=b;}
template< class T> inline  void AMax(T &a,T b){ if(a<b)a=b;}
template< class T> inline T Min(T a,T b){ return a>b?b:a;}
template< class T> inline T Max(T a,T b){ return a>b?a:b;}
const  int maxn =  2222 ;
int cover[maxn<< 2] ;
double sum[maxn<< 2], s[maxn] ;
struct Seg{
     double l, r, h ;
     int d ;
}seg[maxn] ;
int cmp1( const  void *a,  const  void *b){
     return (*(Seg *)a).h < (*(Seg *)b).h ? - 1 :  1 ;
}
int cmp2( const  void *a,  const  void *b){
     return *( double *)a < *( double *)b ? - 1 :  1 ;
}
void setSeg( double l,  double r,  int d,  double h,  int cnt){
    seg[cnt].l = l ;
    seg[cnt].r = r ;
    seg[cnt].d = d ;
    seg[cnt].h = h ;
}
void pushup( int rt,  int l,  int r){
     if(cover[rt])   sum[rt] = s[r+ 1] - s[l] ;
     else  if(l==r)   sum[rt] =  0 ;
     else            sum[rt] = sum[rt<< 1] + sum[rt<< 1| 1] ;
}
int find( double val,  int r){
     int l =  0 ;
     while(l<=r){
         int m = (l + r) >>  1 ;
         if(val==s[m])    return m ;
         if(val>s[m]) l = m +  1 ;
         else    r = m -  1 ;
    }
     return - 1 ;
}
void update( int L,  int R,  int d,  int l,  int r,  int rt){
     if(L<=l&&r<=R){
        cover[rt] += d ;
        pushup(rt, l, r) ;
         return ;
    }
     int m = (l + r) >>  1 ;
     if(L<=m)    update(L, R, d, lson) ;
     if(R>m)     update(L, R, d, rson) ;
    pushup(rt, l, r) ;
}
int main(){
     int n, t= 1, i, x, y, j, m ;
     double a, b, c, d, ans ;
     while(~SD(n)&&n){
        x = y =  0 ;
        FF(i, n){
            SSF(a, b) ;SSF(c, d) ;
            s[y++] = a ;
            s[y++] = c ;
            setSeg(a, c,  1, b, x++) ;
            setSeg(a, c, - 1, d, x++) ;
        }
        qsort(seg, x,  sizeof(Seg), cmp1) ;
        qsort(s, x,  sizeof( double), cmp2) ;
        m =  1 ;
         for(i= 1; i<y; i++)   if(s[i]!=s[i- 1])    s[m++] = s[i] ;
        SET(sum,  0) ;
        SET(cover,  0) ;
        ans =  0 ;
        FF(i, x- 1){
             int l = find(seg[i].l, m- 1) ;
             int r = find(seg[i].r, m- 1) -  1 ;
             if(l<=r)    update(l, r, seg[i].d,  0, m- 11) ;
            ans += sum[ 1] * (seg[i+ 1].h - seg[i].h) ;
        }
        printf( " Test case #%d\n ", t++) ;
        printf( " Total explored area: %.2lf\n\n ", ans) ;
    }
     return  0 ;
}

你可能感兴趣的:(ant)