線段樹求矩形面積並 掃瞄線 離散化

2021-07-11 02:08:32 字數 2360 閱讀 4732

顧名思義,掃瞄法就是用一根想象中的線掃過所有矩形,在寫**的過程中,這根線很重要。方向的話,可以左右掃,也可以上下掃。方法是一樣的,這裡我用的是由下向上的掃瞄法。

如上圖所示,座標系內有兩個矩形。位置分別由左下角和右上角頂點的座標來給出。上下掃瞄法是對x軸建立線段樹,矩形與y平行的兩條邊是沒有用的,在這裡直接去掉。如下圖。

現想象有一條線從最下面的邊開始依次向上掃瞄。線段樹用來維護當前覆蓋在x軸上的線段的總長度,初始時總長度為0。用ret來儲存矩形面積總和,初始時為0。

由下往上掃瞄,掃瞄到矩形的底邊時將它插入線段樹,掃瞄到矩形的頂邊時將底邊從線段樹中刪除。而在**中實現的方法就是,每條邊都有乙個flag變數,底邊為1,頂邊為-1。

用cover陣列(通過線段樹維護)來表示某x軸座標區間內是否有邊覆蓋,初始時全部為0。插入或刪除操作直接讓cover += flag。當cover > 0 時,該區間一定有邊覆蓋。

開始掃瞄到第一條線,將它壓入線段樹,此時覆蓋在x軸上的線段的總長度l為10。計算一下它與下一條將被掃瞄到的邊的距離s(即兩條線段的縱座標之差,該例子裡此時為3)。

則 ret += l * s. (例子裡增量為10*3=30)

結果如下圖

掃瞄到第二條邊,將它壓入線段樹,計算出此時覆蓋在x軸上的邊的總長度。

例子裡此時l=15。與下一條將被掃瞄到的邊的距離s=2。 ret += 30。 如下圖所示。

接下來掃瞄到了下方矩形的頂邊,從線段樹中刪除該矩形的底邊,並計算接下來面積的增量。如下圖

此時矩形覆蓋的總面積已經計算完成。 可以看到,當共有n條底邊和頂邊時,只需要從下往上掃瞄n-1條邊即可計算出總面積。

定義節點和線段:

1

class

treenode2;

11 typedef struct

12line;

建樹:

1

void buildtree(int k, int l, intr)2

13int mid = (l + r) >> 1

; 14 buildtree(k << 1

, l, mid);

15 buildtree(k << 1|1

, mid, r);

16 }

更新:

1

void updatetree(int k, int l, int r, int

flag)29

if(node[k].flag)

10return

; 11

if(node[k].mid <=l)

12 updatetree(k << 1|1

, l, r, flag);

13else

if(node[k].mid >=r)

14 updatetree(k << 1

, l, r, flag);

15else

1620 }

查詢有效長度:

1

void getlength(intk)2

8if(node[k].flag)

9return

; 10 getlength(k << 1

); 11 getlength(k << 1|1

); 12 }

找離散後的位置:

1

int getindex(double num, int

length)

215 }

排序,離散化:

1

for(i = 0; i < n; i ++)

215 sort(x, x+j);

16 sort(seg, seg+j, cmp);

17 k = 1

; 18

for(i = 1; i < j; i ++)

19

線段樹求矩形面積並 掃瞄線 離散化

顧名思義,掃瞄法就是用一根想象中的線掃過所有矩形,在寫 的過程中,這根線很重要。方向的話,可以左右掃,也可以上下掃。方法是一樣的,這裡我用的是由下向上的掃瞄法。如上圖所示,座標系內有兩個矩形。位置分別由左下角和右上角頂點的座標來給出。上下掃瞄法是對x軸建立線段樹,矩形與y平行的兩條邊是沒有用的,在這...

線段樹 掃瞄線 離散化求面積並(hdu1542)

講解的很生動。分析 首先我們將矩形的上下邊分為上位邊 即y座標大的那條平行於x軸的邊 和下位邊 y座標小的平行於x軸的邊 然後我們把所有矩形的上下位邊按照他們y座標從小到大排序 需要把x座標離散化,這樣才能用線段樹來維護資訊.所謂離散化,就是將元素排序,去重,這樣得到乙個陣列a,這個陣列就是建立線段...

線段樹輔助 掃瞄線法計算矩形面積並

分析 2.重點 掃瞄線法 假想有一條掃瞄線,從左往右 從右往左 或者從下往上 從上往下 掃瞄過整個多邊形 或者說畸形。多個矩形疊加後的那個圖形 如果是豎直方向上掃瞄,則是離散化橫座標,如果是水平方向上掃瞄,則是離散化縱座標。下面的分析都是離散化橫座標的,並且從下往上掃瞄的。掃瞄之前還需要做乙個工作,...