POJ 1177 Picture(線段樹 掃瞄線)

2021-10-02 18:16:23 字數 2079 閱讀 3130

鏈結:poj-1177 picture

給出平面直角座標系上n

nn(0≤n

≤5000

0\le n\le 5000

0≤n≤50

00)個矩形,求所有矩形合併後的所有線段長度之和。

以計算水平線段(平行於x

xx軸)的長度之和為例,豎直掃瞄線(平行於y

yy軸)水平掃過各矩形的左、右邊界

可以發現,每掃過單位水平長度,水平線段長度之和應當增加當前豎直方向的線段數目∗2*2

∗2

故要用線段樹維護豎直方向的覆蓋線段數目,較為特殊的一點是,雖然是區間修改,但是並不需要下傳延遲標記(lazy tag),因為

遍歷同一矩形的左、右邊界時分別需要加入、刪除該覆蓋,故線段樹的增加和刪除操作是成對出現的

我們只需要知道整體的覆蓋線段數目,即線段樹根節點的值,無需進一步區間查詢操作

隨後計算豎直線段(平行於y

yy軸)的長度之和,做相同處理即可;

此外,要先對資料做離散化處理,不再用座標,而是用第幾號線段至第幾號線段來表示邊界,更便於處理,詳見**。

#include

#define lowbit(x) ((x)&(-(x)))

using

namespace std;

typedef

long

long ll;

const

int inf=

0x3f3f3f3f

;const

int maxn=

1e4+10;

int n,x[maxn]

,n,y[maxn]

,m;struct rectangle

r[maxn]

;struct border

;vector x[maxn]

,y[maxn]

;void

prework()

//離散化);

x[r[i]

.c].

push_back

(border);

y[r[i]

.b].

push_back

(border);

y[r[i]

.d].

push_back

(border);

}}struct node

t[maxn<<2]

;void

push_up

(int rt)

else

//未被直接整體覆蓋

}void

updata

(int rt,

int l,

int r,

int ql,

int qr,

int op)

//op=1:增加矩陣

int mid=

(l+r)

>>1;

if(ql<=mid)

updata

(rt<<

1,l,mid,ql,qr,op);if

(qr>mid)

updata

(rt<<1|

1,mid+

1,r,ql,qr,op)

;push_up

(rt);}

intmain()

prework()

;int ans=0;

for(

int i=

1;i<=n;i++

)memset

(t,0

,sizeof

(t))

;for

(int i=

1;i<=m;i++

)printf

("%d\n"

,ans)

;return0;

}

POJ 1177 Picture 矩形周長並

題意很簡單,但是周長並比面積並又稍微麻煩了一些 這時候要開乙個numseg儲存豎邊的個數。再開lbd,rbd分別表示邊界,這樣是為了幫助刪除重合的邊 id sdj22251 prog subset lang c include include include include include incl...

POJ 1177 Picture 矩形周長並

題意很簡單,但是周長並比面積並又稍微麻煩了一些 這時候要開乙個numseg儲存豎邊的個數。再開lbd,rbd分別表示邊界,這樣是為了幫助刪除重合的邊 id sdj22251 prog subset lang c include include include include include incl...

POJ 1177 Picture 矩形周長並

題意 給出 n 個矩形,可以相互覆蓋,求所有矩形合在一起的輪廓總長度。分析 先對所有矩形按左下角的y 座標排序,讓矩形的所有點向 x 軸投影,記錄所有的投影的x值,對x 排序,分段累加x 座標差值 如果 s i y1 up 說明兩個矩形沒有交集,即新的矩形沒有被前乙個矩形覆蓋到 res 2 righ...