题目:http://poj.org/problem?id=1151
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> using namespace std; const int N = 10005; struct node { int l,r; int cov; double len; }; struct line { double x; double y1; double y2; int f; bool operator < (const line &a) const { return x < a.x; } }; class SegTree { private: node tree[N]; double num[N]; int ncount; public: SegTree(double a[],int n) { for(int i=0;i<n;i++) num[i] = a[i]; ncount = n; Build(0,n-1,1); } void Build(int l,int r,int rt) { tree[rt].l = l; tree[rt].r = r; tree[rt].cov = 0; tree[rt].len = 0; if(l+1 == r) return; int mid = (l+r)>>1; Build(l,mid,2*rt); Build(mid,r,2*rt+1); } void Insert(int l,int r,int p) { if(tree[p].l == l && tree[p].r == r) { tree[p].cov++; tree[p].len = num[r] - num[l]; return; } int mid = (tree[p].l + tree[p].r)>>1; if(r <= mid) Insert(l,r,2*p); else if(l >= mid) Insert(l,r,2*p+1); else { Insert(l,mid,2*p); Insert(mid,r,2*p+1); } if(tree[p].cov == 0) tree[p].len = tree[2*p].len + tree[2*p+1].len; } void Delete(int l,int r,int p) { if(tree[p].l == l && tree[p].r == r) { tree[p].cov--; if(tree[p].cov <= 0) { if(tree[p].l+1 < tree[p].r) tree[p].len = tree[2*p].len + tree[2*p+1].len; else tree[p].len = 0; } return; } int mid = (tree[p].l + tree[p].r)>>1; if(r <= mid) Delete(l,r,2*p); else if(l >= mid) Delete(l,r,2*p+1); else { Delete(l,mid,2*p); Delete(mid,r,2*p+1); } if(tree[p].cov == 0) tree[p].len = tree[2*p].len + tree[2*p+1].len; } double getLen() { return tree[1].len; } }; int main() { int test=0,n; double x1,y1,x2,y2; double yval[N]; line data[N]; while(~scanf("%d",&n)) { if(n==0) break; test++; int l1 = 0; int l2 = 0; for(int i=0;i<n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); yval[l1++] = y1; yval[l1++] = y2; data[l2].x = x1; data[l2].y1 = y1; data[l2].y2 = y2; data[l2].f = -1; l2++; data[l2].x = x2; data[l2].y1 = y1; data[l2].y2 = y2; data[l2].f = 1; l2++; } sort(yval,yval+l1); sort(data,data+l2); l1 = unique(yval,yval+l1) - yval; double sum = 0; SegTree stree(yval,l1); for(int i=0;i<l2-1;i++) { int l,r; l = lower_bound(yval,yval+l1,data[i].y1) - yval; r = lower_bound(yval,yval+l1,data[i].y2) - yval; if(data[i].f == -1) stree.Insert(l,r,1); else stree.Delete(l,r,1); sum += stree.getLen() * (data[i+1].x - data[i].x); } printf("Test case #%d\n", test); printf("Total explored area: "); printf("%.2lf\n\n", sum); } return 0; }