HDU 1255 覆蓋的面積 線段樹的掃瞄線演算法

2021-09-26 11:07:06 字數 3291 閱讀 3442

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

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

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

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

2

51 1 4 2

1 3 3 7

2 1.5 5 4.5

3.5 1.25 7.5 4

6 3 10 7

30 0 1 1

1 0 2 1

2 0 3 1

7.62

0.00

依託於線段樹的掃瞄線演算法。

給定的圖形是二維的。線段樹的區間表示一維(高),另外一維(底邊長度)用線段樹動態更新來體現。

題目要求至少覆蓋兩次的區域面積,擴充套件一下,求至少覆蓋k次的區域面積。

1、將資料離散化,建立權值線段樹

2、乙個左下角座標(x1,y1)且右上角座標(x2,y2)的矩形可以用兩個四元組表示:(x1,y1,y2,1)和(x2,y1,y2,-1)。所有矩形的四元組按照第乙個元素x公升序排列。第乙個元素x表示更新順序,y1和y2表示更新的區間,第四個元素為1表示掃瞄到乙個新的矩形,為-1表示乙個舊矩形的結束。

3、葉子結點的值表示這個點被覆蓋的次數。因為所有矩形對區間[ y1 , y2 ]一定是先+1後-1,所以所有結點的值自始至終都是非負的。因此,如果區間的lazy值已經大於等於k了,那麼這個區間的覆蓋次數也一定大於等於k,查詢的時候可以直接返回區間長度了。

4、每掃瞄到乙個高(四元組),就查詢並更新一次。

#include

#include

#include

using namespace std;

typedef

long

long ll;

const

int n=

1010

,k=2

;//k是至少覆蓋的次數

int n,cnt;

double b[n<<1]

,v[n<<1]

,sum[n<<1]

;struct node

node

(double xx,

double yy,

double zz,

int kk)

bool operator<

(const node oth)

const

}a[n<<3]

;struct nodetr[n<<3]

;void

pushdown

(int m)

return;}

void

build

(int m,

int l,

int r)

void

update

(int m,

int l,

int r,

int k)

pushdown

(m);

int mid=

(tr[m]

.l+tr[m]

.r)>>1;

if(r<=mid)

update

(m<<

1,l,r,k)

;else

if(l>mid)

update

(m<<1|

1,l,r,k)

;else

return;}

double

query

(int m,

int l,

int r)

pushdown

(m);

int mid=

(tr[m]

.l+tr[m]

.r)>>1;

if(r<=mid)

return

query

(m<<

1,l,r);if

(l>mid)

return

query

(m<<1|

1,l,r)

;return

query

(m<<

1,l,mid)

+query

(m<<1|

1,mid+

1,r);}

intgetid

(double x)

intmain()

//四元組排序

int en=n<<1;

sort

(a,a+en)

;//離散用的陣列排序

sort

(b,b+cnt)

;//b陣列去重

cnt=

unique

(b,b+cnt)

-b;//計算區間長度

for(

int i=

1;i) v[i]

=b[i]

-b[i-1]

;//計算區間長度字首陣列

sum[0]

=0;for

(int i=

1;i) sum[i]

=sum[i-1]

+v[i]

;//建樹

build(1

,1,cnt-1)

;//第乙個四元組進樹

update(1

,getid

(a[0

].y)

,getid

(a[0

].z)-1

,a[0

].k)

;//掃瞄

double ans=0;

for(

int i=

1;i)//輸出

printf

("%.2f\n"

,ans);}

return0;

}

hdu 1255 覆蓋的面積 線段樹

記錄3個變數。sum i 當前區間被覆蓋2次及兩次以上的面積。num i 當前區間被覆蓋1次及一次以上的面積。cover i 覆蓋的lazy標記。對於每乙個區間.更新操作如下 void push up int now if cover rt 1 if cover rt 2 那麼剩下的問題就是簡單的區...

hdu 1255 覆蓋的面積(線段樹求面積交)

給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的區域的面積.雖說覆蓋兩次區域的面積,但是這道題實際上就是求矩形的面積交。膜拜能夠想出這種解法的神牛,竟然能把實際的東西用這麼抽象的語言表示出來,實在是佩服,現在關於掃瞄線的題才做了幾道,沒有對其深刻理解,但是多練總可以理解的,奮鬥吧!acmer!我是...

HDU 1255 覆蓋的面積(線段樹求矩形面積交)

題意 給出n個矩形,求出至少被兩塊矩形覆蓋的面積。思路 跟面積並類似的做法,不同的是每個節點要額外維護乙個至少被覆蓋兩次的長度dcnt,此外還是要維護至少覆蓋一次的長度cnt,然後每次由當前結點的cover標記和子節點的dcnt,cnt值來推出當前結點的dcnt,cnt值。include inclu...