标签:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=14795
#include <iostream> #include <cstring> #include <string> #include <algorithm> #define left rt<<1 #define right rt<<1|1 using namespace std; const int MAXN = 100 + 5; struct Segment { double l, r, h; int s; Segment() {} Segment(double l, double r, double h, int s):l(l),r(r),h(h),s(s) {} bool operator < (const Segment& a) const { return h < a.h; } } seg[MAXN << 1]; double len[MAXN << 3]; int add[MAXN << 3]; double x[MAXN << 1]; void pushup(int rt, int l, int r) { if(add[rt]) len[rt] = x[r+1] - x[l]; else if(l == r) len[rt] = 0; else len[rt] = len[left] + len[right]; } void update(int ql, int qr, int x, int rt, int l, int r) { if(ql <= l && r <= qr) { add[rt] += x; pushup(rt, l, r); return; } int m = (l + r) >> 1; if(ql <= m) update(ql, qr, x, left, l, m); if(qr > m) update(ql, qr, x, right, m+1, r); pushup(rt, l, r); } int Bsearch(double *x, int n, double key) { int l = 0, r = n - 1; while(l <= r) { // [l, r] int m = (l + r) >> 1; if(x[m] == key) return m; else if(x[m] < key) l = m+1; else r = m-1; } } int main () { int n, segNum, xNum, kase=1; double x1, y1, x2, y2, ans; while(scanf("%d", &n) != EOF && n) { segNum = xNum = 0; for(int i=0; i<n; i++) { scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); x[xNum++] = x1; x[xNum++] = x2; seg[segNum++] = Segment(x1, x2, y1, 1); seg[segNum++] = Segment(x1, x2, y2, -1); } sort(x, x+xNum); sort(seg, seg+segNum); int cur = 1; for(int i=1; i<xNum; i++) { if(x[i] != x[i-1]) x[cur++] = x[i]; } xNum = cur; // 用下面的memset替代build memset(add, 0, sizeof(add)); memset(len, 0, sizeof(len)); ans = 0; for(int i=0; i<segNum-1; i++) { int l = Bsearch(x, xNum, seg[i].l); //这里之所以要减1,是因为每一个下标都代表的是一个区间,比如下标l其实代表的是区间[l,l+1] int r = Bsearch(x, xNum, seg[i].r) - 1; if(l <= r) update(l, r, seg[i].s, 1, 0, xNum-1); ans += len[1] * (seg[i+1].h - seg[i].h); } printf("Test case #%d\nTotal explored area: %.2lf\n\n", kase++, ans); } return 0; }
HDU 1542 —— Atlantis 【矩形面积并:扫描线】
标签:
原文地址:http://www.cnblogs.com/AcIsFun/p/5469619.html