POJ 1177 Picture(扫描线 + 线段树 矩形覆盖区域周长的并)
2013-02-01 23:54
591 查看
题意:
求矩形所覆盖的区域周长的并。
思路:
1. 首先是对于 x 轴线的扫描,这点和上题POJ 1151类似,不过求周长和面积不同的一点是前面一条线和后面一条线的差。
2. 对于高,要另外设置几组参数和标记:ynum[rt] 表示在 rt 表示的区域范围内,y 坐标方向竖线的个数
3. lbd[rt], rbd[rt] 分别表示左右边界是否被扫描线覆盖,这样的话求线段的并的时候变能够判断边界部分是否有重合。
4. 以上操作是在每两条扫描线之间进行的,所以这里需要一个抽象的过程,不过也不算多难理解。
5. 周长和面积的区别是:周长要一直循环 m(扫描线的个数) 次,因为最上层的一条线毕竟需要加入周长范围内。
求矩形所覆盖的区域周长的并。
思路:
1. 首先是对于 x 轴线的扫描,这点和上题POJ 1151类似,不过求周长和面积不同的一点是前面一条线和后面一条线的差。
2. 对于高,要另外设置几组参数和标记:ynum[rt] 表示在 rt 表示的区域范围内,y 坐标方向竖线的个数
3. lbd[rt], rbd[rt] 分别表示左右边界是否被扫描线覆盖,这样的话求线段的并的时候变能够判断边界部分是否有重合。
4. 以上操作是在每两条扫描线之间进行的,所以这里需要一个抽象的过程,不过也不算多难理解。
5. 周长和面积的区别是:周长要一直循环 m(扫描线的个数) 次,因为最上层的一条线毕竟需要加入周长范围内。
#include <iostream> #include <algorithm> using namespace std; #define lhs l, m, rt << 1 #define rhs m + 1, r, rt << 1 | 1 const int maxn = 20010; int xsum[maxn << 2], ynum[maxn << 2]; int cnt[maxn << 2]; bool lbd[maxn << 2], rbd[maxn << 2]; structSegment { int l, r, h, v; Segment() { } Segment(int _l, int _r, int _h, int _v) : l(_l), r(_r), h(_h), v(_v) { } bool operator < (const Segment& other) { return h < other.h; } } seg[maxn] ; void PushUp(int l, int r, int rt) { if (cnt[rt]) { lbd[rt] = rbd[rt] = true; xsum[rt] = r - l + 1; ynum[rt] = 2; } else if (l == r) { lbd[rt] = rbd[rt] = false; xsum[rt] = ynum[rt] = 0; } else { lbd[rt] = lbd[rt << 1]; rbd[rt] = rbd[rt << 1 | 1]; xsum[rt] = xsum[rt << 1] + xsum[rt << 1 | 1]; ynum[rt] = ynum[rt << 1] + ynum[rt << 1 | 1]; if (lbd[rt << 1 | 1] && rbd[rt << 1]) ynum[rt] -= 2; } } void Update(int beg, int end, int value, int l, int r, int rt) { if (beg <= l && r <= end) { cnt[rt] += value; PushUp(l, r, rt); return ; } int m = (l + r) >> 1; if (beg <= m) Update(beg, end, value, lhs); if (end > m) Update(beg, end, value, rhs); PushUp(l, r, rt); } int main() { int n; while (~scanf("%d", &n)) { int m = 0; int beg = 10000, end = -10000; for (int i = 0; i < n; ++i) { int a, b, c, d; scanf("%d %d %d %d", &a, &b, &c, &d); beg = min(a, beg); end = max(c, end); seg[m++] = Segment(a, c, b, 1); seg[m++] = Segment(a, c, d, -1); } sort(seg, seg + m); int ret = 0, pre = 0; for (int i = 0; i < m; ++i) { if (seg[i].l < seg[i].r) Update(seg[i].l, seg[i].r - 1, seg[i].v, beg, end - 1, 1); ret += abs(xsum[1] - pre); pre = xsum[1]; ret += ynum[1] * (seg[i+1].h - seg[i].h); } printf("%d\n", ret); } return 0; }
相关文章推荐
- poj 1177 & hdu 1828 Picture 线段树 扫描线求矩形周长并
- poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)
- POJ-1177-Picture(线段树+扫描线+离散化)[矩形周长并]
- poj 1177 Picture(扫描线+矩形周长并)
- 【线段树 + 扫描线】poj 1177 pictures 矩形周长并
- poj 1177 Picture(线段树求矩形周长并)
- hdu 1828 / poj/pku 1177(Picture)(线段树求矩形覆盖面周长)
- hdu 1828、poj1177求矩形周长并 线段树 扫描线
- POJ - 1177/HDU - 1828 Picture(线段树-矩形并周长)
- POJ-1177 Picture (线段树 求矩形周长)
- POJ-1177 Picture 矩形覆盖周长并
- poj 1177 Picture 【线段树 扫描线 求轮廓周长】
- poj 1177 Picture(线段树+矩形周长并)
- 【线段树 && 扫描线 && 周长】POJ - 1177 Picture
- POJ 1177 Picture 求多个矩形周长 -
- POJ 1177 Picture(扫描线求周长)
- [HDOJ1828]Picture(扫描线,线段树,矩形并周长)
- POJ 1177 Picture(矩形并的周长)
- POJ 1177-Picture线段树+离散化+扫描线求矩形周长并
- POJ - 1177 Picture(线段树 扫描线 区间合并)