矩形面积并 HDU1542

来源:互联网 发布:html data属性 js 编辑:程序博客网 时间:2024/06/09 20:19

扫描线+线段树维护(每个节点所在的区间被覆盖的次数,和被覆盖的长度的和)

线段树[l,r]表示 d1(r)1d1(l)f(x)dx , f(x)=1(当且仅当x位置被覆盖),d(x)表示x离散化的映射。

#include<bits/stdc++.h>using namespace std;template<class T>  struct Discretization {    #define BUF_SIZE 2005    //using dtype = int;    T buf[BUF_SIZE];    int tot;    Discretization() {        tot = 0;    }    void insert(T a) {        buf[tot++] = a;    }    void discretization() {        sort(buf, buf + tot);        tot = unique(buf, buf+tot) - buf;    }    int get(T a) {        int pos = lower_bound(buf, buf + tot, a) - buf;        return pos < tot && buf[pos] == a ? pos: -1;    }    #undef BUF_SIZE};Discretization<double> dst;template<class T>struct SegTree { //Seg[l,r] = Sum(d(l), d(r+1)) 即query(1,1)代表区间[buf[1],buf[2]]覆盖的线段长度    #define TREE_SIZE 2005    struct node {        int l, r, cnt;        T sum;    } a[TREE_SIZE << 2];    void pushup(int pos) {        if(a[pos].cnt)  {            a[pos].sum = dst.buf[a[pos].r] - dst.buf[a[pos].l-1];            //printf("???? %f\n",a[pos].sum);        }        else a[pos].sum = a[pos << 1].sum + a[(pos << 1) ^ 1].sum;    }    void build(int l, int r, int pos = 1) {        a[pos].l = l;        a[pos].r = r;        a[pos].sum = a[pos].cnt = 0;        if(l != r) {            int mid = (l + r) >> 1;            build(l, mid, pos << 1);            build(mid + 1, r, (pos << 1) ^ 1);        }    }    void insert(int l, int r, int v, int pos = 1) {        if(a[pos].l == l && a[pos].r == r) {            a[pos].cnt += v;            pushup(pos);            return;        }        int mid = (a[pos].l + a[pos].r) >> 1;        if(r <= mid) insert(l, r, v, pos << 1);        else if(l > mid) insert(l, r, v, (pos << 1) ^ 1);        else {            insert(l, mid, v, pos << 1);            insert(mid + 1, r, v, (pos << 1) ^ 1);        }        pushup(pos);    }    #undef TREE_SIZE};SegTree<double> st;struct Segment {    double l, r, pos;    int v;    bool operator < (const Segment &s) const {        return pos < s.pos;    }};Segment seg[2005];int main ()  {      int n;    int cs = 1;    while(~scanf("%d",&n) && n) {        int tot = 0;        dst.tot = 0;        while(n--) {            double x1, y1, x2, y2;            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);            dst.insert(x1);            dst.insert(x2);            dst.insert(y1);            dst.insert(y2);            seg[tot++] = (Segment){y1,y2,x1,1};            seg[tot++] = (Segment){y1,y2,x2,-1};        }        sort(seg, seg + tot);        dst.discretization();        st.build(1, dst.tot);        int i = 0;        double res = 0;        while(i < tot) {            double pos = seg[i].pos;            for(;i < tot && seg[i].pos == pos;i++) {                int l = dst.get(seg[i].l), r = dst.get(seg[i].r);                //printf("insert l=%f r=%f v=%d\n",seg[i].l,seg[i].r,seg[i].v);                st.insert(l+1, r, seg[i].v);            }            //printf("pos=%f sum=%f\n",pos,st.a[1].sum);            if(i < tot) res += st.a[1].sum * (seg[i].pos - pos);        }        printf("Test case #%d\nTotal explored area: %.2f\n\n",cs++,res);    }    return 0;  } 
原创粉丝点击