顧名思義,掃瞄法就是用一根想象中的線掃過所有矩形,在寫**的過程中,這根線很重要。方向的話,可以左右掃,也可以上下掃。方法是一樣的,這裡我用的是由下向上的掃瞄法。
如上圖所示,座標系內有兩個矩形。位置分別由左下角和右上角頂點的座標來給出。上下掃瞄法是對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 }
1for(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.重點 掃瞄線法 假想有一條掃瞄線,從左往右 從右往左 或者從下往上 從上往下 掃瞄過整個多邊形 或者說畸形。多個矩形疊加後的那個圖形 如果是豎直方向上掃瞄,則是離散化橫座標,如果是水平方向上掃瞄,則是離散化縱座標。下面的分析都是離散化橫座標的,並且從下往上掃瞄的。掃瞄之前還需要做乙個工作,...