HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)
2014-08-09 16:50
309 查看
题目链接
题意:中文题意。
分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt》=0改成cnt>=2就行了,、
但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于
2,但是之前的那个线段加上现在的已经覆盖2次了。
题意:中文题意。
分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt》=0改成cnt>=2就行了,、
但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于
2,但是之前的那个线段加上现在的已经覆盖2次了。
#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <cstdlib> #include <algorithm> #define LL __int64 #define lson l, mid, 2*rt #define rson mid+1, r, 2*rt+1 const int maxn = 2000+10; using namespace std; int n; double y[maxn]; struct node { int l, r, c; double cnt, lf, rf, more; //cnt还是代表覆盖的长度,增加了more代表两次及以上覆盖的长度 }tr[4*maxn]; struct Line { double x, y1, y2; int f; }line[maxn]; bool cmp(Line a, Line b) { return a.x < b.x; } void build(int l, int r, int rt) { tr[rt].l = l; tr[rt].r = r; tr[rt].c = 0; tr[rt].cnt = 0; tr[rt].more = 0; tr[rt].rf = y[r]; tr[rt].lf = y[l]; if(l+1==r) return; int mid = (l+r)/2; build(l, mid, 2*rt); build(mid, r, 2*rt+1); } void calen(int rt) { if(tr[rt].c==0) { if(tr[rt].l+1==tr[rt].r) { tr[rt].cnt = 0; tr[rt].more = 0; } else { tr[rt].cnt = tr[2*rt].cnt+tr[2*rt+1].cnt; tr[rt].more = tr[2*rt].more+tr[2*rt+1].more; } } if(tr[rt].c==1) //注意这一步是关键 { tr[rt].cnt = tr[rt].rf-tr[rt].lf; if(tr[rt].l+1==tr[rt].r) //因为没有注意是否到最后,错了一遍 tr[rt].more = 0; else tr[rt].more = tr[2*rt].cnt + tr[2*rt+1].cnt; //为1的时候如果下面也有就加上 } if(tr[rt].c>=2) { tr[rt].more = tr[rt].rf-tr[rt].lf; tr[rt].cnt = tr[rt].more; } } void update(int rt, Line e) { if(e.y1==tr[rt].lf && e.y2==tr[rt].rf) { tr[rt].c += e.f; calen(rt); return; } if(e.y2<=tr[2*rt].rf) update(2*rt, e); else if(e.y1>=tr[2*rt+1].lf) update(2*rt+1, e); else { Line tmp; tmp = e; tmp.y2 = tr[2*rt].rf; update(2*rt, tmp); tmp = e; tmp.y1 = tr[2*rt+1].lf; update(2*rt+1, tmp); } calen(rt); } int main() { int t, i, cnt; double x1, x2, y1, y2, ans; scanf("%d", &t); while(t--) { scanf("%d", &n); cnt = 1; ans = 0; for(i = 1; i <= n; i++) { scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); line[cnt].x = x1; line[cnt].y1 = y1; line[cnt].y2 = y2; line[cnt].f = 1; y[cnt++] = y1; line[cnt].x = x2; line[cnt].y1 = y1; line[cnt].y2 = y2; line[cnt].f = -1; y[cnt++] = y2; } sort(y+1, y+cnt); sort(line+1, line+cnt, cmp); cnt --; build(1, cnt, 1); update(1, line[1]); for(i = 2; i <= cnt; i++) { ans += tr[1].more*(line[i].x - line[i-1].x); update(1, line[i]); } printf("%.2lf\n", ans); } return 0; }
相关文章推荐
- HDU 1255 覆盖的面积 (线段树 + 离散化 + 扫描线)
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
- HDU 1255 覆盖的面积[离散化 + 扫描线 + 线段树]
- HDU 1255 覆盖的面积[离散化 + 扫描线 + 线段树]
- hdu1255 覆盖的面积 线段树+里离散化求矩形面积的交
- HDU-1255 覆盖的面积(线段树扫描线模板+离散化+加点修改题)
- HDU-1255 覆盖的面积 线段树 + 扫描线
- hdu 1255 覆盖的面积 线段树扫描线求重叠面积
- 线段树 扫描线 HDU 1255 覆盖的面积
- hdu 1255 覆盖的面积 (线段树扫描线 计算两次覆盖的面积)
- HDU 1255 覆盖的面积 线段树 扫描线
- Hdu 1255 覆盖的面积 线段树+矩形面积并
- HDU 1255 覆盖的面积 (线段树+扫描线+离散化)
- hdu 1255 覆盖的面积 离散化+线段树
- HDU 1255 覆盖的面积 线段树+扫描线求面积并
- HDU 1542【线段树--矩形面积的并,扫描线+离散化】
- hdu 4419 线段树 扫描线 离散化 矩形面积
- CDOJ 1335-求恰好k次覆盖矩形面积并- (线段树 扫描线 离散化)
- HDU 1255 覆盖的面积(线段树扫描线求面积的交)
- HDU 1255 覆盖的面积(线段树求矩形面积交)