HDU 1542/POJ 1151 Atlantis (scaning line + segment tree)

A template of discretization + scaning line + segment tree.
It's easy to understand, but a little difficult for coding as it has a few details.

#include"Head.cpp"

const int N=207;

double x[N<<1];

struct Point{
    double l,r,h;
    int w;
    bool operator< (const Point &b)const{
        return h < b.h;
    }
}a[N<<2];

struct SegmentTree{
    int l,r,w;
    double len;
}t[N<<3];


#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r

inline void Pushup(int rt){
    if(t[rt].w != 0)
        t[rt].len = x[t[rt].r+1] - x[t[rt].l];
    else if(t[rt].l == t[rt].r)
        t[rt].len = 0;
    else // t[rt].w == 0
        t[rt].len = t[rt<<1].len + t[rt<<1|1].len;
}

inline void Build(int rt,int l,int r){
    t[rt] = (SegmentTree){l, r, 0, 0};
    if(l == r) return;
    int mid = (l>>1) + (r>>1) + (l&r&1);
    Build(lson),Build(rson);
}

inline void Updata(int rt,int L,int R,int val){
    if(t[rt].l >= L && t[rt].r <= R){
        t[rt].w += val;
        Pushup(rt);
        return;
    }
    int mid = (t[rt].l>>1) + (t[rt].r>>1) +(t[rt].l&t[rt].r&1);
    if(L <= mid) Updata(rt<<1, L, R, val);
    if(R > mid) Updata(rt<<1|1, L, R, val);
    Pushup(rt);
}

inline int FindPos(int l,int r,double val){
    int mid;
    while(l<=r){
        mid = (l>>1) + (r>>1) + (l&r&1);
        if(x[mid] > val)
            r = mid - 1;
        else if(x[mid] < val)
            l = mid + 1;
        else // x[mid] == val
            break;
    }
    return mid;
}

int main(){
    int task=0;
    int n;
    while(~scanf("%d",&n) && n!=0){
        int cnt=0;
        
        R(i,1,n){
            double x_1,x_2,y_1,y_2;
            scanf("%lf%lf%lf%lf",&x_1,&y_1,&x_2,&y_2);
            
            // 1 -> floor, -1 -> ceiling
            x[++cnt] = x_1;
            a[cnt] = (Point){x_1, x_2, y_1, 1};
            x[++cnt] = x_2;
            a[cnt] = (Point){x_1, x_2, y_2, -1};
        }
        
        sort(x+1, x+cnt+1);
        sort(a+1, a+cnt+1);
        Build(1, 1, cnt);
        
        double ans = 0;
        R(i,1,cnt-1){
            int l = FindPos(1, cnt, a[i].l),
                r = FindPos(1, cnt, a[i].r) - 1;
            Updata(1, l, r, a[i].w);
            ans += t[1].len * (a[i+1].h - a[i].h);
        }
        
        printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++task, ans);
    }
    
    return 0;
}
/*
2
10 10 20 20
15 15 25 25.5
0
*/

转载于:https://www.cnblogs.com/bingoyes/p/11144537.html

你可能感兴趣的:(HDU 1542/POJ 1151 Atlantis (scaning line + segment tree))