首页 > 代码库 > HDU 1255 覆盖的面积 (扫描线 线段树 离散化)

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 }