線段樹求周長求交面積的做法

2021-05-21 19:25:33 字數 1674 閱讀 5561

求周長的做法是對每個段,用線段樹計算出不相交的區間個數,至於求區間個數,有點像掃瞄線的做法,也是先排序,排序之後就是求括號序列有多少個區間,很有技巧。然後就是段的長度*區間個數*2,然後對矩形座標進行關於y=x對稱,再做一次就是完整的周長了。

受求周長做法的啟發,可以得到求矩形交面積的做法,需要乙個一維線段樹,記錄x方向線段的資訊,還要乙個二維線段樹記錄各部分是否被覆蓋,一維線段樹在某線段處add=1且掃瞄的線段為+時記錄下y的位置,到add=2且掃瞄線段為-時記錄下y的位置,這兩個y以及x的線段就是交的部分,放入二維線段樹中。這樣迴圈完了之後再計算出二維線段樹包含的面積。

周長的程式我寫了(poj1177),感覺學了不少,這裡的線段樹比一般的線段樹更精妙些,不預先建立,需要時才建立,可以沒有左孩子或右孩子,這並非是為了效率,而是為了便於左右孩子繼承節點的add值。

矩形交面積的做法只是推想而已。

#include #include using namespace std;

long n;

struct tagrect

rects[5000];

short xmin,xmax,ymin,ymax;

short ins_left, ins_right, ins_add;

struct tagedge

inline bool operator < (const tagedge& edge) const

else if (y > edge.y)

else

else

}return y < edge.y;

}}edges[10000];

struct tagsegtreenode

}segtree[1 << 16];

void input(void)

}long insert(long pos)

short mid = ((node.left + node.right) >> 1);

if (ins_right <= mid)

return insert(pos);

} else if (ins_left >= mid)

return insert(pos);

} pos <<= 1;

if (!node.blc)

retval = insert(pos);

++pos;

if (!node.brc)

retval += insert(pos);

return retval;

}inline long insert(long pos, short left, short right, short add)

long calchorzlen(void)

sort(edges, edges + (n << 1));

long retval = 0;

segtree[1].set(xmin, xmax, 0);

for (i = 0; i < (n << 1); ++i)

return retval;

}int main(void)

swap(xmin, ymin);

swap(xmax, ymax);

l += calchorzlen();

l <<= 1;

printf("%d/n", l);

return 0;

}

線段樹矩形面積並,面積交,周長並

include include include include using namespace std const int maxn 2000 10 define lson l,mid,rt 1 define rson mid 1,r,rt 1 1 struct rec rec maxn 2 str...

hdu 1255 覆蓋的面積(線段樹求面積交)

給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的區域的面積.雖說覆蓋兩次區域的面積,但是這道題實際上就是求矩形的面積交。膜拜能夠想出這種解法的神牛,竟然能把實際的東西用這麼抽象的語言表示出來,實在是佩服,現在關於掃瞄線的題才做了幾道,沒有對其深刻理解,但是多練總可以理解的,奮鬥吧!acmer!我是...

線段樹 面積交

給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的區域的面積.input輸入資料的第一行是乙個正整數t 1 t 100 代表測試資料的數量.每個測試資料的第一行是乙個正整數n 1 n 1000 代表矩形的數量,然後是n行資料,每一行包含四個浮點數,代表平面上的乙個矩形的左上角座標和右下角座標,矩形的...