【POJ 1151】Atlantis

【原题题面】传送门

【题面大意】

给出N个矩形,求矩形的面积并。

【题解思路】

线段树扫描线入门题。

实现的一些细节:

存边的信息用结构体,根据x的大小排序

从每段的y值的开始操作

线段树维护的是的信息

该段被覆盖了几次

左端点贡献为1(左端点以后的线段都是正贡献),右端点贡献为-1(右端点以后的值都没有贡献1+-1=0)

由于区间修改到哪一段是固定的,所以不需要写push

 【code】

#include<bits/stdc++.h>
using namespace std;
#define File ""
#define ll long long
inline void file(){
    freopen(File".in","r",stdin);
    freopen(File".out","w",stdout);
}
const int mxn = 100+3;
int n,m,T(0);
map<double,int> val;
double raw[mxn<<1];
struct T{
    int l,r,c;
    double len;
}tr[mxn<<4];
struct P{
    double x,y1,y2;
    int k;
    bool operator <(const P t) const {
        return x < t.x;
    }
}p[mxn<<1];
#define ls p<<1
#define rs p<<1|1

inline void B(int p,int l,int r){
    tr[p].l = l,tr[p].r = r;
    tr[p].c = tr[p].len = 0;
    if(l==r) return;
    int mid = l+r >>1;
    B(ls,l,mid),B(rs,mid+1,r);//哈。哈。哈。
}

inline void U(int p,int l,int r,int k){
    if(l <= tr[p].l && tr[p].r <= r){
        tr[p].len = ((tr[p].c += k) ? raw[tr[p].r+1] - raw[tr[p].l] : 0);
    }
    if(tr[p].l == tr[p].r) return;
    int mid = tr[p].l+tr[p].r >>1;
    if(l <= mid) U(ls,l,r,k);
    if(r > mid) U(rs,l,r,k);
    tr[p].len = (tr[p].c ? raw[tr[p].r+1]-raw[tr[p].l] : tr[ls].len+tr[rs].len);
}

int main(){
//    file();
    while(++T){
        scanf("%d",&n);
        if(!n) return 0;
        for(int i = 1; i <= n; ++i){
            double x1,y1,x2,y2;
            scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
            int id = i<<1;
            raw[id-1] = y1,raw[id] = y2;
            p[id-1].x = x1,p[id-1].y1 = y1,p[id-1].y2 = y2,p[id-1].k = 1;
            p[id].x = x2,p[id].y1 = y1,p[id].y2 = y2,p[id].k = -1;
        }
        n <<= 1;
        sort(raw + 1,raw + n + 1);
        int m = unique(raw+1,raw+n+1) - (raw+1);
        for(int i = 1;i <= m; ++i) val[raw[i]] = i;
        sort(p + 1,p + n + 1);
        B(1,1,m-1);
        double ans = 0;
        for(int i = 1;i < n; ++i){
            int y1 = val[p[i].y1],y2 = val[p[i].y2]-1;
            U(1,y1,y2,p[i].k);
            ans += tr[1].len * (p[i+1].x - p[i].x);
        }
        printf("Test case #%d\n",T);
        printf("Total explored area: %.2f\n",ans);
        puts("");
    }
    return 0;
}
View Code

 

posted @ 2019-05-15 18:02  ve-2021  阅读(127)  评论(0编辑  收藏  举报