hdu1255--覆蓋的面積(線段樹+離散化+掃描線),hdu1255--線段

來源:互聯網
上載者:User

hdu1255--覆蓋的面積(線段樹+離散化+掃描線),hdu1255--線段

E - 覆蓋的面積 Time Limit:5000MS      Memory Limit:32768KB      64bit IO Format:%I64d & %I64uSubmit Status

Description

給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的地區的面積. 


 

Input

輸入資料的第一行是一個正整數T(1<=T<=100),代表測試資料的數量.每個測試資料的第一行是一個正整數N(1<=N<=1000),代表矩形的數量,然後是N行資料,每一行包含四個浮點數,代表平面上的一個矩形的左上方座標和右下角座標,矩形的上下邊和X軸平行,左右邊和Y軸平行.座標的範圍從0到100000. 

注意:本題的輸入資料較多,推薦使用scanf讀入資料. 
 

Output

對於每組測試資料,請計算出被這些矩形覆蓋過至少兩次的地區的面積.結果保留兩位小數. 
 

Sample Input

 251 1 4 21 3 3 72 1.5 5 4.53.5 1.25 7.5 46 3 10 730 0 1 11 0 2 12 0 3 1 
 

Sample Output

 7.630.00 
 

剛剛接觸掃描線,一開始只是求了n個矩形的並的體積,這次求的是覆蓋兩次以上的面積。

首先給出了n個矩形的座標,對於y座標離散化,從左向右掃描,在求並的面積時,用標記sum1儲存了出現過的線段的長度,使用(p[i].x-p[i-1].x)*cl[1].sum1求解了每一部分的面積,而在求覆蓋面積的時候,還要定義一個變數sum2,儲存下在控制區內出現兩次的總和。

在sum1的push_up中,如果lazy標記不是0,那麼該段全部出現,那麼cl[rt].sum1 = cl[rt].r - cl[rt].l ;否則該節點的值就是左右兩個子樹的和。

在sum2的push_up中,如果lazy表標記的結果是2,那麼該段全部出現,sum2的值就是該段的長度,如果lazy的標記是1表示該段在該節點全部出現,那麼出現過兩次的長度就是在該節點的左右子節點中出現的長度,即 cl[rt].sum2  = cl[rt<<1].sum1 + cl[rt<<1|1].sum1 ;,如果該節點的lazy是0,那麼該段的sum2也就等於左右子節點的sum2之和。


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 3000struct node1{    double x, y1 , y2 ;    int flag ;} p[maxn];struct node{    double l , r ;    double sum1 , sum2 ;} cl[maxn<<3];double s[maxn<<1] ;int lazy[maxn<<3] ;bool cmp(node1 a,node1 b){    return a.x <b.x ;}void push_up(int rt){    if( lazy[rt] )        cl[rt].sum1 = cl[rt].r - cl[rt].l ;    else        cl[rt].sum1 = cl[rt<<1].sum1 + cl[rt<<1|1].sum1 ;    if( lazy[rt] > 1 )        cl[rt].sum2 = cl[rt].r - cl[rt].l ;    else if(lazy[rt] == 1)        cl[rt].sum2 = cl[rt<<1].sum1 + cl[rt<<1|1].sum1 ;    else        cl[rt].sum2 = cl[rt<<1].sum2 + cl[rt<<1|1].sum2 ;}void creat(int rt,int l,int r){    cl[rt].l = s[l] ;    cl[rt].r = s[r] ;    if( r - l >1 )    {        creat(rt<<1,l,(l+r)/2);        creat(rt<<1|1,(l+r)/2,r);        push_up(rt);    }    else    {        cl[rt].sum1 = cl[rt].sum2 = 0 ;        cl[rt<<1].sum1 = cl[rt<<1].sum2 = 0 ;        cl[rt<<1|1].sum1 = cl[rt<<1|1].sum2 = 0 ;    }}void update(int rt,double l,double r,int flag){    if( cl[rt].l== l && cl[rt].r == r )    {        lazy[rt] += flag ;        push_up(rt);    }    else    {        if( cl[rt<<1].r > l )        {            double x = min(r,cl[rt<<1].r);            update(rt<<1,l,x,flag);        }        if( cl[rt<<1|1].l < r )        {            double x = max(l,cl[rt<<1|1].l);            update(rt<<1|1,x,r,flag);        }        push_up(rt);    }}int main(){    int t , n , m , i , j ;    double x1, y1 , x2 , y2 , ans ;    scanf("%d", &t);    while(t--)    {        scanf("%d", &n);        for(i = 0 ; i < n ; i++)        {            scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);            p[i].x = x1 ;            p[i].y1 = y1 ;            p[i].y2 = y2 ;            p[i].flag = 1 ;            p[i+n].x = x2 ;            p[i+n].y1 = y1 ;            p[i+n].y2 = y2 ;            p[i+n].flag = -1 ;            s[i+1] = y1 ;            s[i+n+1] = y2 ;        }        memset(lazy,0,sizeof(lazy));        sort(s+1,s+2*n+1);        sort(p,p+2*n,cmp);        m = unique(s+1,s+(2*n+1))-(s+1);        creat(1,1,m);        update(1,p[0].y1,p[0].y2,p[0].flag);        ans = 0 ;        for(i = 1 ; i < 2*n ; i++)        {            ans += (p[i].x - p[i-1].x)*cl[1].sum2 ;            update(1,p[i].y1,p[i].y2,p[i].flag);        }        printf("%.2lf\n", ans);    }    return 0;}




POJ上的線段樹

這個有時候得看具體題目的,我一般不管的,數組能開多大就多大,反正看重的是時間而不是空間。我認為有可能是為了離散化的需要,也可能是其他方面。。對於線段樹,現在只會寫一維的,對於周長樹,面積樹還沒寫過。。
LZ別太介意,看到同是熱衷poj 的愛好者,忍不住說了幾句。。
 
菜鳥教,hdu3265,給個思路就行,謝了O(∩_∩)O,詳細見下

這個不需要二維線段樹。
用二維線段樹的話可能大材小用了,複雜度也會比較高。
該題只要使用掃描線+一維線段樹就行了。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.