HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)
题意:中文题意。
分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt》=0改成cnt>=2就行了,、
但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于
2,但是之前的那个线段加上现在的已经覆盖2次了。
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 #define LL __int64 8 #define lson l, mid, 2*rt 9 #define rson mid+1, r, 2*rt+1 10 const int maxn = 2000+10; 11 using namespace std; 12 int n; 13 double y[maxn]; 14 struct node 15 { 16 int l, r, c; 17 double cnt, lf, rf, more; //cnt还是代表覆盖的长度,增加了more代表两次及以上覆盖的长度 18 }tr[4*maxn]; 19 struct Line 20 { 21 double x, y1, y2; 22 int f; 23 }line[maxn]; 24 bool cmp(Line a, Line b) 25 { 26 return a.x < b.x; 27 } 28 void build(int l, int r, int rt) 29 { 30 tr[rt].l = l; tr[rt].r = r; 31 tr[rt].c = 0; tr[rt].cnt = 0; 32 tr[rt].more = 0; 33 tr[rt].rf = y[r]; tr[rt].lf = y[l]; 34 if(l+1==r) return; 35 int mid = (l+r)/2; 36 build(l, mid, 2*rt); 37 build(mid, r, 2*rt+1); 38 } 39 void calen(int rt) 40 { 41 if(tr[rt].c==0) 42 { 43 if(tr[rt].l+1==tr[rt].r) 44 { 45 tr[rt].cnt = 0; tr[rt].more = 0; 46 } 47 else 48 { 49 tr[rt].cnt = tr[2*rt].cnt+tr[2*rt+1].cnt; 50 tr[rt].more = tr[2*rt].more+tr[2*rt+1].more; 51 } 52 } 53 if(tr[rt].c==1) //注意这一步是关键 54 { 55 tr[rt].cnt = tr[rt].rf-tr[rt].lf; 56 if(tr[rt].l+1==tr[rt].r) //因为没有注意是否到最后,错了一遍 57 tr[rt].more = 0; 58 else 59 tr[rt].more = tr[2*rt].cnt + tr[2*rt+1].cnt; //为1的时候如果下面也有就加上 60 } 61 if(tr[rt].c>=2) 62 { 63 tr[rt].more = tr[rt].rf-tr[rt].lf; 64 tr[rt].cnt = tr[rt].more; 65 } 66 } 67 void update(int rt, Line e) 68 { 69 if(e.y1==tr[rt].lf && e.y2==tr[rt].rf) 70 { 71 tr[rt].c += e.f; 72 calen(rt); 73 return; 74 } 75 if(e.y2<=tr[2*rt].rf) update(2*rt, e); 76 else if(e.y1>=tr[2*rt+1].lf) update(2*rt+1, e); 77 else 78 { 79 Line tmp; 80 tmp = e; 81 tmp.y2 = tr[2*rt].rf; update(2*rt, tmp); 82 tmp = e; 83 tmp.y1 = tr[2*rt+1].lf; update(2*rt+1, tmp); 84 } 85 calen(rt); 86 } 87 int main() 88 { 89 int t, i, cnt; 90 double x1, x2, y1, y2, ans; 91 scanf("%d", &t); 92 while(t--) 93 { 94 scanf("%d", &n); 95 cnt = 1; ans = 0; 96 for(i = 1; i <= n; i++) 97 { 98 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 99 line[cnt].x = x1; line[cnt].y1 = y1; 100 line[cnt].y2 = y2; line[cnt].f = 1; 101 y[cnt++] = y1; 102 line[cnt].x = x2; line[cnt].y1 = y1; 103 line[cnt].y2 = y2; line[cnt].f = -1; 104 y[cnt++] = y2; 105 } 106 sort(y+1, y+cnt); 107 sort(line+1, line+cnt, cmp); 108 cnt --; 109 build(1, cnt, 1); 110 update(1, line[1]); 111 for(i = 2; i <= cnt; i++) 112 { 113 ans += tr[1].more*(line[i].x - line[i-1].x); 114 update(1, line[i]); 115 } 116 printf("%.2lf\n", ans); 117 } 118 return 0; 119 }