1. 程式人生 > >矩形面積並 HDU1542

矩形面積並 HDU1542

掃描線+線段樹維護(每個節點所在的區間被覆蓋的次數,和被覆蓋的長度的和)

線段樹[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; }