HDU-2461 Rectangles 线段树,矩形面积并
2012-07-30 11:29
387 查看
首先申明此方法POJ超时,HDU压线过,优化版见/article/4949189.html
线段树的写法与上面链接中的离散化版本的想法是相近的,只不过这里仅仅是通过线段树来保留某一x区域的多个矩形的面积并。
代码如下:
线段树的写法与上面链接中的离散化版本的想法是相近的,只不过这里仅仅是通过线段树来保留某一x区域的多个矩形的面积并。
代码如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <map> #include <algorithm> using namespace std; int N, M, Q, cnt; map<int,int>mp; struct Rectangle { int x1, y1, x2, y2; }e[25]; struct High { int y; bool operator < (High temp) const { return y < temp.y; } bool operator == (High temp) const { return y == temp.y; } }H[50]; struct xLine { int x, y1, y2, sign; bool operator < (xLine temp) const { return x < temp.x; } }Line[50]; struct Node { int l, r, lazy; }s[200]; void build(int p, int l, int r) { s[p].l = l, s[p].r = r; s[p].lazy = 0; // 初始化为被覆盖了0次 if (l != r) { int mid = (l + r) >> 1; build(p<<1, l, mid); build(p<<1|1, mid+1, r); } } void push_up(int p) { } void push_down(int p) { if (s[p].lazy != 0) { s[p<<1].lazy += s[p].lazy; s[p<<1|1].lazy += s[p].lazy; s[p].lazy = 0; } } void modify(int p, int l, int r, int val) { if (l == s[p].l && r == s[p].r) { s[p].lazy += val; } else { int mid = (s[p].l + s[p].r) >> 1; push_down(p); if (r <= mid) { modify(p<<1, l, r, val); } else if (l > mid) { modify(p<<1|1, l, r, val); } else { modify(p<<1, l, mid, val); modify(p<<1|1, mid+1, r, val); } push_up(p); } } int query(int p) { if (s[p].l == s[p].r) { return (bool)(s[p].lazy) * (H[s[p].r].y - H[s[p].l-1].y); } else { push_down(p); return query(p<<1) + query(p<<1|1); } } int main() { int c, sum, ca = 0; while (scanf("%d %d", &N, &M), N|M) { for (int i = 1; i <= N; ++i) { scanf("%d %d %d %d", &e[i].x1, &e[i].y1, &e[i].x2, &e[i].y2); } printf("Case %d:\n", ++ca); for (int t = 1; t <= M; ++t) { sum = 0; mp.clear(); scanf("%d", &Q); for (int j = 1, k = 0; j <= Q; ++j, k += 2) { scanf("%d", &c); Line[k].x = e[c].x1, Line[k+1].x = e[c].x2; Line[k].sign = 1, Line[k+1].sign = -1; // 定义 1为入边,-1为出边 Line[k].y1 = e[c].y1, Line[k].y2 = e[c].y2; Line[k+1].y1 = e[c].y1, Line[k+1].y2 = e[c].y2; H[k].y = e[c].y1, H[k+1].y = e[c].y2; } sort(H, H+2*Q); // 对y轴坐标进行离散话 cnt = unique(H, H+2*Q) - H; // 去重 for (int i = 0; i < cnt; ++i) { mp[H[i].y] = i; } sort(Line, Line+2*Q); for (int i = 0; i < 2*Q; ++i) { Line[i].y1 = mp[Line[i].y1]; Line[i].y2 = mp[Line[i].y2]; // 将y坐标进行离散化 } build(1, 0, cnt-1); // 建立一个空的树来表示整个纵坐标的覆盖情况 modify(1, Line[0].y1+1, Line[0].y2, Line[0].sign); for (int i = 1; i < (Q << 1); ++i) { // 遍历每一个 sum += query(1) * (Line[i].x - Line[i-1].x); modify(1, Line[i].y1+1, Line[i].y2, Line[i].sign); } printf("Query %d: %d\n", t, sum); } puts(""); } return 0; }
相关文章推荐
- hdu 线段树 (矩形面积并+离散化+二分查找)
- HDU 1542 Atlantis(线段树求矩形面积并)
- HDU 2056 Rectangles (求两个相交矩形面积)
- HDU 3265——Posters(线段树+面积并+矩形分割)
- HDU 1255 覆盖的面积(线段树求矩形面积交)
- HDU 5722 Jewelry【线段树,矩形面积并】
- hdu 1542 & poj 1151 Atlantis 线段树扫描线求矩形面积并
- 2017 icpc 南宁赛区 F.Overlapping Rectangles(重叠矩形的最大面积+线段树模板)
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
- Hdu 1255 覆盖的面积 线段树+矩形面积并
- hdu1542 Atlantis【矩形面积并+线段树】
- HDU 1255 矩形覆盖面积(线段树)
- Hdu 1542 Atlantis + Hdu 1255 覆盖的面积 (线段树矩形面积并)
- HDU1542 Atlantis(扫描线+矩形面积并+线段树)
- HDU 1542【线段树--矩形面积的并,扫描线+离散化】
- HDU - 1255 覆盖的面积(线段树-矩形交面积)
- poj 1151 && hdu 1542 求矩形面积并(线段树)
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
- HDU 2056 Rectangles(矩形面积交)
- Hdu 1542 Atlantis 线段树 求矩形面积并