掃瞄線 演算法學習筆記

2021-10-05 16:13:25 字數 2390 閱讀 7878

一般如果是從左往右掃的話,首先用結構體表示圖形(長方形或正方形)的左右兩邊;

struct ddu[n*2]

;

f 表示該邊時入邊還是出邊,入邊為 1 , 出邊表示 -1 ;

x 表示該邊的x座標,y1 表示該邊的上邊y座標,y2 表示該邊的下邊y座標;

如圖:這個還沒完,可以發現y的取值範圍為1-1e9,因為我們線段樹維護的是y(這個後面講),所以肯定爆空間,圖形數量是1e5,所以離散化y是必須的一步;

y離散化完了,就再把結構體du以x由小到大排序,然後從左往右掃;

再說線段樹維護什麼;

struct nodetr[n*8]

;

l,r意義不變,len表示的就是該區間的長度,lz表示該區間被加入的次數(也就是上面的入邊和出邊 f );

最最最重要也最難的部分來了:

voi***(

int k)

記住,掃瞄線區間修改操作不需要往下轉標記,也就說不需要每個葉子結點的值都改變;

所以只要pp,向上傳就可以;

當lz有值時,就是說該區間有邊加入時,那麼該區間的長度len直接等於r-l(注意l,r以被離散化,val表示離散化前的原值),這裡還有個r+1,也是非常非常重要難理解的一部分,之後再講;

當lz沒有值時,只要加上左右區間的長度即可;

我們查詢的時候,一般是直接查全域性的長度,tr[1].len;

所以最後我們只要區間修改,和直接查詢即可;

ll ans=0;

for(

int i=

1;i)

修改的值就是du[i].f,表示該邊是加入還是出去,這裡為啥是y2-1,這跟前面為啥是r+1有聯絡;

現在講前面最重要,最難理解的黃色部分:一切的一切都是離散化導致的;

假設,l=1,r=m,我們要在區間[1,m]中加1,是不是直接len=len[d]-len[l]+len[r]-len[d+1];

這樣算出來的len是錯的,為啥?因為d–d+1之間的距離我們沒算,這也是線段樹維護的y的距離而不是傳統的線段樹的區別了;

全部**來自這道題:

洛谷·p5490 【模板】掃瞄線

**:

#include

#define ll unsigned long long

#define pa pair

#define ls k<<1

#define rs k<<1|1

#define inf 0x3f3f3f3f

using

namespace std;

const

int n=

100010

;const

int m=

50100

;const ll mod=

10007

;int n,x_1[n]

,x_2[n]

,y_1[n]

,y_2[n]

,a[n*2]

,cnt,tot,val[n*2]

;struct ddu[n*2]

;struct nodetr[n*8]

;void

build

(int l,

int r,

int k)

voi***(

int k)

void

update

(int l,

int r,

int w,

int k)

int d=

(tr[k]

.l+tr[k]

.r)>>1;

if(l<=d)

update

(l,r,w,ls);if

(r>d)

update

(l,r,w,rs);pp

(k);

}bool

cmp(d p,d q)

intmain()

sort

(a+1

,a+cnt+1)

; cnt=

unique

(a+1

,a+cnt+1)

-a-1

;for

(int i=

1;i<=n;i++

)sort

(du+

1,du+tot+

1,cmp)

;build(1

,cnt-1,

1); ll ans=0;

for(

int i=

1;i)printf

("%lld\n"

,ans)

;return0;

}

掃瞄線演算法

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

X 掃瞄線演算法

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

區域填充之掃瞄線演算法

區域的填充可以根據區域的填充,採用不同的填充演算法,而其中有掃瞄線類演算法和種子填充演算法。這裡,先介紹掃瞄線類演算法之有序邊表的掃瞄線演算法。其他什麼種子填充 邊界標誌演算法 4連通區域的遞迴演算法 8連通區域的遞迴演算法 掃瞄線種子填充演算法比較簡單。其實有序邊表其實領會了也好理解,關鍵是將思想...