掃瞄線講解,動態開點版線段樹

2022-05-08 01:18:13 字數 2047 閱讀 3799

首先,掃瞄線是幹什麼的?掃瞄線一般運用在圖形上面,它和它的字面意思十分相似,就是一條線在整個圖上掃來掃去,它一般被用來解決圖形面積,周長等問題,以一道例題為例。給出n個正方形,這些正方形在平面直角座標系中互相重疊擺放,但四條邊都與座標軸平行,例如下圖所示。那麼知道題目了,怎麼運用呢?首先我們需要知道怎麼用暴力解決這個問題,根據可知圖中的面積是sabcd+shefg-sidje暴力搜尋是個好東西,但是當資料範圍大了怎麼辦?這裡就要講到掃瞄線。

掃瞄線對於這道例題可以抽象為這四條紫色的直線(如上圖l1,l2,l3,l4),仔細觀察,可以看出這四條線把這個圖形分割成三個矩形,那麼我們就可以直接求這三個矩形再加和是不是就可以了?那麼現在難點來了,怎樣求這些矩形的面積。我們可以把題目中給的矩形的邊轉換成直線(如下圖),即只留下這四條邊,這四條線就是整個做法的核心。既然四條線已經看出來了,那麼我們就可以一眼看出,面積就是從頭到現在的掃瞄線的重影減去已經結束的長方形的邊的投影承上兩條掃瞄線的間距。再把這些乘積加在一起。

下面就將如何實現了,首先我們可以想到用線段樹求區間和來求這些投影的長度,那麼區間如此之大(-1e8~1e8),怎麼能建樹呢?不會空間**嗎?所以就應該運用動態開點線段樹,算一下每乙個掃瞄線開乙個節點,那麼就是n個,一共有log2

1e8層所以是可以開的下的。根據這個說法,每一條邊應該進行排序,由於掃瞄是從左到右,所以排序應該是把橫座標從小到大排序,所以每條邊有三個屬性:位置即橫座標,從那個點開始,從那個點結束,這兩給點分別是縱座標的兩個端點。

struct line

line[2001];

bool cmp1(const line &a,const line &b)

掃瞄線查詢

最難的要數修改,如果現在的節點被現在要加的邊完全覆蓋,那麼直接修改就好啦,否則要遞迴的尋找他的兒子,如果沒有兒子則動態開點出來,這邊是修改的想法,當然在修改時不要忘記修改cover的值。

void change(int l,int r,int x,int y,int &p,int delta)

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

if(x<=mid)

change(l,mid,x,y,lp,delta);

if(y>mid)

change(mid+1,r,x,y,rp,delta);

}掃瞄線修改

(新更)我們用這個**,思考一道題目,就是bzoj1645城市地平線,我們可以知道tle這個事實,但是為什麼呢?由於我們每一次我們都需要查詢,每一次查詢都是至少o(n)以上的時間複雜度,這樣我們整體的時間複雜度就是大於o(n^2),我們需要優化一下,我們可以開乙個叫做sum的陣列,也就是我們把上面的sum陣列重新定義一下就可以了,在這裡我們定義sum陣列為當前區間之中所有的邊的和,那麼我們很容易知道,如果當前的區間的cover值大於零,sum陣列就位當前區間的r-l+1,如果cover等於零,sum陣列的值就等於他的左右兒子的sum陣列的值相加,是不是很簡單?根據定義整個圖形中的線段和就位跟的sum值。下面是更改後的區間修改以及pushup函式,當然由於我們可以o(1)求出整個圖形之中的線段和,所以find函式就沒有了。

void pushup(int p,int l,int r)

void change(int l,int r,int x,int y,int &p,int delta)

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

if(x<=mid) change(l,mid,x,y,lson[p],delta);

if(y>mid) change(mid+1,r,x,y,rson[p],delta);

pushup(p,l,r);

}

線段樹 掃瞄線

pku 1151 hdu1542 atlantis 矩形面積並 題意 給出n個矩形,每個矩形給出左下角座標,右上角座標。然後求矩形並的總面積 思路 浮點數先要離散化 然後把矩形分成兩條邊,上邊和下邊,對橫軸建樹,然後從下到上掃瞄上去,用cnt表示該區間下邊比上邊多幾個,sum代表該區間內被覆蓋的線段...

掃瞄線 線段樹

問題描述 小明的家旁邊有條河流,但最近,周圍的三個工廠開始向這條河排放汙水,這條河的一部分被汙染了,被乙個工廠汙染的部分可以看做乙個矩形,現在小明想知道這條河被汙染的面積是多少。輸入 第一行乙個整數t,表示有多少組資料,之後每一組資料報括三行,每一行有lx,ly,rx,ry四個整數,表示被乙個工廠汙...

線段樹 掃瞄線

掃瞄線問題主要利用了線段樹。因為矩形的並集比較難算,所以我們可以用 sum 掃瞄線被截長度 所掃瞄的高度 來求和。而這樣做發現可以用線段樹來優化,具體優化方式如下 所掃瞄的高度比較好求,主要是掃瞄線被截長度需要優化。我們可以設橫邊有乙個a權值,如果該邊是矩陣的下邊則設為1,相反就設為 1,這樣如果一...