矩形面積並 HDU1542
阿新 • • 發佈:2019-02-07
掃描線+線段樹維護(每個節點所在的區間被覆蓋的次數,和被覆蓋的長度的和)
線段樹[l,r]表示
#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;
}