(使用線段樹實現的)掃瞄線演算法

2022-08-13 09:03:11 字數 1942 閱讀 6510

乙個空間中存在若干矩形,且矩形的放置方向一致——(矩形的每條邊必然和x或者y軸平行)

求這些矩形覆蓋的總面積的大小。(存在若干個矩形相互重疊的問題)

考慮線段樹可以logn的時間內做到區間覆蓋,區間設定特殊值。因此應當採用線段樹進行計算。

考慮當將矩形切割成兩條形如,x1,x2,y,val的命令,其中x1,x2代表當前上線/下線的長度;y代表當前高度,val取1或-1分別帶至矩形的起始邊和結束邊。

對於當前應用場景,具有很明顯的特點,及,對於任意乙個矩形,都必然將初始邊和結束邊加進線段樹中。則若某給定區間為a,b時,不存在當a,b邊對應的結束邊還未被加進線段樹時就被清零或部分清零的可能性。

因此,對於任意區間,都有顯而易見的兩種狀態:

1,明確的知道該區間已經被填滿。——則區間長度為區間所能表示的上下限之差。

2,不知道該區間是否被填滿。——則區間長度為兩個子區間之差。

對於2情況有乙個子狀態:及當前區間僅僅包含乙個元素:(a == b-1) ——我**中區間定義為左閉右開。對於該區間,若無明確的增加指令,則應當認為區間長度為0。

#includeusing

namespace

std;

#define ll long long

const ll maxn= 1

<<19

;const ll maxm = 2333

;int t,n,sizeofmap =0

;;class

node

;node tree[maxn];

class

command

command(){}

command(

double x1,double x2,double y,int

v)

};command commands[maxm];

int command_number = 0

;void tree_init(int a,int b,int

now)

double

arr[maxm];

int find_pos(double

tar)

void update(int a,int b,int now,int

key)

else tree[now].sum = arr[r]-arr[l];

return

; }

if(a else

update(a,b,rc,key);

if(tree[now].number == 0

)

else tree[now].sum = arr[r]-arr[l];

return

;

}int cases = 1

;void

init()

sort(arr,arr+sizeofmap);

sort(commands,commands+command_number);

tree_init(

0,sizeofmap+2,1

);

double last = 0.0

;

double ans = 0

;

for(int i=0;ii)

double x1 =commands[i].x1;

double x2 =commands[i].x2;

int val =commands[i].val;

update(find_pos(x1),find_pos(x2),

1,val);

}//couttest case #%d\ntotal explored area: %.2f\n\n

",cases++,ans);

}int

main()

return0;

}

掃瞄線演算法

給出幾個矩形對角端點座標,求這些矩形整體覆蓋的面積。基本思想如下圖 先離散化。掃瞄線 是一根想象中的虛線,從左往右掃瞄,遇到 矩形 則成為 事件 遇到 起始邊 則update相應區間的 厚度 或者 覆蓋次數 covercnt 1。遇到 結束邊 則update相應區間的 厚度 covercnt 1。用...

X 掃瞄線演算法

多邊形有兩種重要的表示方法 頂點表示和點陣表示 頂點表示是用多邊形的頂點序列來表示多邊形。這種表示直觀 幾何意義強 佔記憶體少,易於進行幾何變換。但由於它沒有明確指出哪些象素在多邊形內,故不能直接用於面著色 點陣表示是用位於多邊形內的象素集合來刻畫多邊形。這種表示丟失了許多幾何資訊 如邊界 頂點等 ...

高階資料結構之線段樹與掃瞄線演算法

1.掃瞄線演算法 1 原理 平面掃瞄線演算法通常由掃瞄線 事件點 當前掃瞄事件點集合構成 通過掃瞄線按照某一方向依次掃瞄,掃瞄事件點,檢查事件點狀態,然後新增或刪除事件點以更新事件點集合。2 看一道經典的問題 lintcode391.數飛機 給出飛機的起飛和降落時間的列表,用 interval 序列...