HDU 1255 覆蓋的面積 (掃描線 線段樹 離散化)

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   for   ar   

題目連結

題意:中文題意。

分析:純手敲,與上一道題目很相似,但是剛開始我以為只是把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 }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.