HDU 3265 Posters
题意:给定一些矩形海报。中间有孔。求贴海报的之后的海报覆盖面积并
思路:海报一张能够分割成4个矩形。然后就是普通的矩形面积并了,利用线段树维护就可以
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N = 50005; struct Node { int l, r, len, cover; int size() {return r - l + 1;} } node[N * 4]; struct Line { int l, r, y, flag; Line() {} Line(int l, int r, int y, int flag) { this->l = l; this->r = r; this->y = y; this->flag = flag; } } line[N * 8]; struct Rec { int x1, y1, x2, y2; Rec() {} Rec(int x1, int y1, int x2, int y2) { this->x1 = x1; this->y1 = y1; this->x2 = x2; this->y2 = y2; } } rec[N * 4]; bool cmp(Line a, Line b) { return a.y < b.y; } int n; int x[4], y[4]; #define lson(x) ((x<<1)+1) #define rson(x) ((x<<1)+2) void pushup(int x) { if (node[x].cover) node[x].len = node[x].size(); else if (node[x].l == node[x].r) node[x].len = 0; else node[x].len = node[lson(x)].len + node[rson(x)].len; } void build(int l, int r, int x = 0) { node[x].l = l; node[x].r = r; if (l == r) { node[x].cover = node[x].len = 0; return; } int mid = (l + r) / 2; build(l, mid, lson(x)); build(mid + 1, r, rson(x)); pushup(x); } void add(int l, int r, int v, int x = 0) { if (l > r) return; if (node[x].l >= l && node[x].r <= r) { node[x].cover += v; pushup(x); return; } int mid = (node[x].l + node[x].r) / 2; if (l <= mid) add(l, r, v, lson(x)); if (r > mid) add(l, r, v, rson(x)); pushup(x); } int main() { while (~scanf("%d", &n) && n) { build(0, 50000); int rn = 0, ln = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < 4; j++) scanf("%d%d", &x[j], &y[j]); rec[rn++] = Rec(x[0], y[0], x[1], y[2]); rec[rn++] = Rec(x[0], y[2], x[2], y[3]); rec[rn++] = Rec(x[0], y[3], x[1], y[1]); rec[rn++] = Rec(x[3], y[2], x[1], y[3]); } for (int i = 0; i < rn; i++) { line[ln++] = Line(rec[i].x1, rec[i].x2, rec[i].y1, 1); line[ln++] = Line(rec[i].x1, rec[i].x2, rec[i].y2, -1); } n = ln; sort(line, line + n, cmp); ll ans = 0; for (int i = 0; i < n; i++) { if (i) ans += (ll)node[0].len * (line[i].y - line[i - 1].y); add(line[i].l, line[i].r - 1, line[i].flag); } printf("%lld ", ans); } return 0; }